An in depth look at Django

In Django, we have a few concepts. We have projects, apps, views, models, templates and a few more bits and bobs. In this article, I want to go through 

  • Django Project
    • App
      • Views.py
      • Models.py
      • Templates
      • admin.py
    • Project Config
      • Settings.py
      • Urls.py

So how do all of these things work and how do they link together?

When a user makes a request

The request is directed to urls.py. Here, it says ‘is there a URL path that has been defined in this file? If there is, which view does it relate to?

I’ve included a snippet of my urls.py for my password generator app below. Let’s take pasword as an example. Here, the request to reach the url www.example.com/password will come in. It’ll be assessed against the urls.py file. It’ll find that, yes, there is a path defined for password.

It then will see that this is associated to the password view and that we’ve applied an alias to the link name=’password’ – which is the name we can use to refer to this elsewhere in the app.

from django.contrib import admin
from django.urls import path
from kodey import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.home, name='home'),
    path('password', views.password, name='password'),
]

The URL has been found in urls.py and redirected to the view

I’m actually going to use a view from a different project here, so you can see a more complex example.

Reading from a model

Here, I have a viewrepo view. Within the view, I query the repo model (described below) and we filter that based on author – where the author must be the currently logged in user. We also create a few more variables based on model queries.

We then create a dictionary at the bottom, which includes each of those things I want to pass to the HTML page. Finally, I render the repo.html page and pass the context dictionary in to be used on the front end.

def viewrepo(request):
    repo_list = repo.objects.filter(author=request.user).order_by('-version')
    countrepo = repo.objects.filter(author=request.user).count()
    today = date.today()
    projects = repo.objects.values('project').distinct().filter(author=request.user)

    context = {'repo_list' : repo_list, 'today': today, 'countrepo':countrepo, 'projects': projects}
    return render(request, 'repo.html', context)

Writing to a model

Here is an example of creating an object within a model. With each of these, we say ‘if the field in the front end form is not empty then save the value to a variable, if it is empty, we will save it as ‘undefined’.

At the end of the view, we create the object and redirect the user back to the main repo URL.

def createrepo(request):
    if request.method == 'POST':
        if request.POST.get('filename') <> '':
            filename = request.POST.get('filename')
        else:
            filename = 'filename not defined'
        if request.POST.get('language') <> '':
            language = request.POST.get('language')
        else:
            language = 'language not defined'
        if request.POST.get('version') <> '':
            version = request.POST.get('version')
        else:
            version = 'version not defined'
        author = request.user
        if request.POST.get('currentstatus') <> '':
            currentstatus = request.POST.get('currentstatus')
        else:
            currentstatus = 'status not defined'
	if request.POST.get('project') <> '':
	    project = request.POST.get('project') 
	else:
	    project = 'project not defined'
		
        if request.POST.get('code') <> '':
            code =  request.POST.get('code')
        else:
            code = 'no code entered'
    else:
        filename='none'
        language='none'
        version='none'
        currentstatus='none'
        code='none'
        author=request.user

    i =  repo.objects.create(filename=filename, project=project, language=language, version=version, author=author, currentstatus=currentstatus, code=code)
    messages.success(request, ('Code Stored'))
    return redirect('repo')

Removing from a model

The below, shows how we would go about deleting a repo. We define t by getting the object from the repo model. That object ID = the ID passed into the request from the form. We then simply write t.delete() to remove the object.

def repo_delete(request):
    t = repo.objects.get(id=request.POST.get('deletebutton'))
    t.delete() # this will update only
    messages.success(request, ('You have deleted a repo'))
    return redirect('repo')

Updating a model

Here we show an example of updating a model. Here, we define t as the ID of the post. Each time, we say ‘if the form is NOT empty, then t.field_name = the value from the form’. We then save t at the very end which commits the changes back.

def editrepo(request):
    t = repo.objects.get(id=request.POST.get('editrepo'))
    
    if request.POST.get('filename') <> '':
        t.filename = request.POST.get('filename')
       
    if request.POST.get('language') <> 'Language':
        t.language = request.POST.get('language')
       
    if request.POST.get('version') <> 'Version':
        t.version = request.POST.get('version')
       
    author = request.user
    if request.POST.get('currentstatus') <> 'Status':
        t.currentstatus = request.POST.get('currentstatus')
    
    if request.POST.get('project') <> '':
        t.project = request.POST.get('project') 
		
    if request.POST.get('code') <> '':
        t.code =  request.POST.get('code')
    
    t.save() # this will update only
    messages.success(request, ('Update Stored'))
    return redirect('repo')

A segway into models

In the above, we saw how the views create, update, query, and delete things from models in Django. Here is the definition of the model. It is simply a way to define the names and datatypes of the fields you require in your model.

class repo(models.Model):
    filename =  models.CharField(max_length=400, default="none")
    language =  models.CharField(max_length=400, default="none")
    version =  models.CharField(max_length=400, default="none")
    author = models.CharField(max_length=400, default="none")
    currentstatus = models.CharField(max_length=400, default="none")
    code = models.TextField(default="none")
    project=models.CharField(max_length=400, default="none")
    def __str__(self):
        return self.text

Displaying it all on the front end

Below you can see lots of examples of rendering on the front end. We have some loops which you can see; some if statements and how to print the actual field values.

{% extends 'base.html' %}
{% block content %}
<div class="row">
   <div class="container">
      <form action="/searchrepo/" name="form1", id="form1" method="post">
         {% csrf_token %}
         <div class="form-group">
            <select  name="projectfilter" class="form-control" id="projectfilter">
               <option>Filter by project</option>
               {% for repo in projects %}
               <option value="{{repo.project}}">{{repo.project}}</option>
               {% endfor %}
            </select>
         </div>
         <button type="submit"  name="add" class="btn btn-warning btn-sm"><i class="fas fa-search"></i> Search</button>
      </form>
   </div>
</div>
<div class="row">
<div class="container">
   {% if repo_list|length == 0 %}
   <h4><font color="#ffc107"><i class="fas fa-arrow-up"></i></font> <font color="white">ADD YOUR FIRST REPO</font></h4>
   {% else %}
   <br>
   <div class="table-responsive">
      <table class="table" style="background-color: #303030;">
         <thead>
            <tr>
               <th scope="col"><font color="ffc107">Filename</font></th>
               <th scope="col"><font color="ffc107">Project</font></th>
               <th scope="col"><font color="ffc107">Language</font></th>
               <th scope="col"><font color="ffc107">Version</font></th>
               <th scope="col"><font color="ffc107">Status</font></th>
               <th scope="col"><font color="ffc107">Code</font></th>
               <th scope="col"><font color="ffc107">Edit</font></th>
               <th scope="col"><font color="ffc107">Delete</font></th>
            </tr>
         </thead>
         <tbody>
            {% for repo in repo_list %}
            <tr>
               <th><font color="#D8D8D8">{{repo.filename }}</font></th>
               <td><font color="#D8D8D8">{{ repo.project }}</font></td>
               <td><font color="#D8D8D8">{{ repo.language }}</font></td>
               <td><font color="#D8D8D8">{{ repo.version }}</font></td>
               <td><font color="#D8D8D8">{{ repo.currentstatus }}</font> </td>
               <td><button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#repoview{{ repo.id }}"> <i class="far fa-eye"></i> </button>  </td>
               <td><button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#editrepo{{repo.id}}"><i class="far fa-edit"></i> </button>  </td>
               <td><button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#deleterepo{{repo.id}}"> <i class="fas fa-times"></i> </button>  </td>
            </tr>
            <!-- DELETE REPO MODAL -->
            <div class="modal fade" id="deleterepo{{repo.id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
               <div class="modal-dialog" role="document">
                  <div class="modal-content">
                     <div class="modal-body" style="background-color: #404040">
                        <div align="right">
                           <button type="button" class="btn btn-warning btn-sm" data-dismiss="modal">
                           <i class="fas fa-times-octagon"></i>Close Window</button>
                        </div>
                        <hr>
                        <font color="white">
                           <form action="/repodelete/" name="form1", id="form1" method="post">
                              {% csrf_token %}   
                              <button name="deletebutton" type="submit"  value="{{ repo.id }}"  class="btn btn-danger btn-sm">
                              <i class="fas fa-times"></i> Yes, Delete It</button>
                           </form>
                     </div>
                  </div>
               </div>
            </div>
            </font>
            <!-- END DELETE REPO MODAL -->
            <!-- VIEW REPO MODAL -->
            <div class="modal fade" id="repoview{{repo.id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
               <div class="modal-dialog modal-lg" role="document">
                  <div class="modal-content">
                     <div class="modal-body" style="background-color: #404040">
                        <div align="right">
                           <button type="button" class="btn btn-warning btn-sm" data-dismiss="modal">
                           <i class="fas fa-times-octagon"></i>Close Window</button>
                        </div>
                        <hr>
                        <font color="white">
                           <div class="form-group">
                              <label>Code</label>
                              <textarea class="form-control" id="exampleFormControlTextarea1" rows="20" name="code">{{ repo.code }}</textarea>
                           </div>
                           </form>
                     </div>
                     </font>
                  </div>
               </div>
            </div>
            <!-- END VIEW REPO MODAL -->
            <!-- EDIT REPO MODAL -->
            <div class="modal fade" id="editrepo{{repo.id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
               <div class="modal-dialog modal-lg" role="document">
                  <div class="modal-content">
                     <div class="modal-body" style="background-color: #404040">
                        <div align="right">
                           <button type="button" class="btn btn-warning btn-sm" data-dismiss="modal">
                           <i class="fas fa-times-octagon"></i>Close Window</button>
                        </div>
                        <hr>
                        <font color="white">
                           <div class="modal-body">
                              <form action="/editrepo/" name="form1", id="form1" method="post">
                                 {% csrf_token %}
                                 <div class="form-group">
                                    <label>Filename</label>
                                    <input type="text" name="filename" value="{{repo.filename}}" class="form-control" id="task" aria-describedby="emailHelp">
                                 </div>
                                 <div class="form-group">
                                    <label>Project</label>
                                    <input type="text" name="project"  value="{{repo.project}}" class="form-control" id="task" aria-describedby="emailHelp">
                                 </div>
                                 <div class="form-group">
                                    <label for="exampleFormControlSelect1">Language</label>
                                    <select class="form-control" name="language" id="exampleFormControlSelect1">
                                       <option>{{repo.language}}</option>
                                       <option>SQL</option>
                                       <option>Python</option>
                                       <option>PHP</option>
                                       <option>HTML</option>
                                       <option>Spark</option>
                                    </select>
                                 </div>
                                 <div class="form-group">
                                    <label for="exampleFormControlSelect1">Version Number</label>
                                    <select class="form-control" name="version" id="exampleFormControlSelect1">
                                       <option>{{repo.version}}</option>
                                       <option>1</option>
                                       <option>2</option>
                                       <option>3</option>
                                       <option>4</option>
                                       <option>5</option>
                                       <option>6</option>
                                       <option>7</option>
                                       <option>8</option>
                                       <option>9</option>
                                       <option>10</option>
                                    </select>
                                 </div>
                                 <div class="form-group">
                                    <label for="exampleFormControlSelect1">Status</label>
                                    <select class="form-control" name="currentstatus" id="exampleFormControlSelect1">
                                       <option>{{repo.currentstatus}}</option>
                                       <option>In Development</option>
                                       <option>In Test</option>
                                       <option>In Production</option>
                                    </select>
                                 </div>
                                 <div class="form-group">
                                    <label>Code</label>
                                    <textarea class="form-control" id="exampleFormControlTextarea1" rows="10" name="code">{{repo.code}}</textarea>
                                 </div>
                                 <button type="submit"  name="editrepo" value="{{repo.id}}" class="btn btn-warning">Edit Repo</button>
                              </form>
                           </div>
                     </div>
                     </font>
                  </div>
               </div>
               <!-- END EDIT REPO MODAL -->
               {% endfor %}
         </tbody>
      </table>
      </div>
   </div>
</div>
{% endif %}
{% endblock %}
Kodey