CHAPTER 3: Django App, Urls,Views, Models and Templates

In this entry, we are about to learn very important things about Django App. If you don’t understand how URLs, VIEWS, MODELS & TEMPLATES work and relate then I’ll assure you you will have dead-end soon so it is important you understand this flow.

Now Django uses the Model View Control (MVC) pattern. For Django, I would say its MVT where T is the Templates. MVC is an architectural design that separates an application into three main logical components:

    1. Model: Model component is responsible for the application data, this may be a database, file or an object it also takes some logics
    2. View/Template: Template is responsible for what is rendered to the user, what the user sees that is the user interface for Django its the HTML page. It’s rendering the data to the user who requested it in a way they can understand. Note I use Template for the sake of Django.
  1. Controller: Controller accepts requests from user/client and takes appropriate action then return results to the user. I request is to update user profile it takes it, load the user data from the database and redirect the client to correct form template. It updates both models and templates.

Even though it is not part of MVC, I would want to add Routing which matches URLs with responsible views which have functions to handle them.

Let’s look at a scenario:

Assume I want to check the date I should return a book that I borrowed from the library,

    • I will go to my browser and type library domain and maybe bookID as part of that URL eg libraryx.lib/CS002343
    • This request will be broadcasted to servers across the internet until the server that can handle that request is found, that is the server that hosts the library website.
    • Once the server has taken that request it will match that URL libraryx.lib/CS002343 against pre-listed URLs until the URL matching this format is found. These listed URLs actually have functions to handle the request that come through them.
  • This request will be sent to the responsible function.
  • Inside this function, we could be loading return_date of the book with the supplied ID and then returning this result to the user who requested it.

All this process takes microseconds

Enough of theory lets understand by practice. 

In Django, we try to keep project structure as clean as possible, for that reason we use apps to separate parts of the project that are less related. like payments and blog on an e-commerce site. Let’s create our ticketing app.

Open Terminal/ CMD and cd into STICKETING where we have Stickenting, venv and manage.py

symons@symons-macbookair:~$ cd STICKETING
symons@symons-macbookair:~/STICKETING$ ls
db.sqlite3  manage.py  Sticketing  venv
symons@symons-macbookair:~/STICKETING$ 

I hope you already know whatever follows $ is the command.

Now we activate our virtual environment:

symons@symons-macbookair:~/STICKETING$ source venv/bin/activate
(venv) symons@symons-macbookair:~/STICKETING$ 

In windows use venv\Scripts\activate .

We create the Django app with the following command:

$ python manage.py startapp ticketing

You should see a new folder named ticketing on the current directory

django-app

Now ticketing is our app. Lets open STICKETING folder with a text editor of your choice, I will use Vscode.

django app folder structure

As you can see a new app comes with some files here I’ll concentrate on models.py and views.py.

We now need to let Django know that we have a new app. Remember our settings.py? its global configuration file for our project. open it on a text editor and find INSTALLED APPs inside it the add ‘ticketing’.It should look like this:

Adding django app to settings.py

adding django app to setings.py

And we are good. let us just check if we can run server still.

(venv) symons@symons-macbookair:~/STICKETING$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

February 18, 2020 - 22:35:13
Django version 2.2.10, using settings 'Sticketing.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

It is running but with a warning, this is because Django comes with other six built-in apps that we can use. These apps need to have a database so we run migrations to create the needed database.

NOTE: To stop the server and allow you to run commands using ctrl+C

(venv) symons@symons-macbookair:~/STICKETING$ python manage.py migrate

The result should be:

server

Now runserver again:

$ python manage.py runserver

The warning is gone. time to write our first URL,

Go to project level (Sticketing) and open url.py in your editor.

Sticketing/urls.py

"""Sticketing URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

You should have this before you do anything, everything inside “”” …”””, are comments in python and you can remove them.

We want http://127.0.0.1:8000/ to be the home page of our project. for now, we will display “Comming Soon” and we will update soon

and to keep the project clean we will redirect requests without any other parameter after domain name to our app’s URL

Sticketing/urls.py

from django.contrib import admin
from django.urls import path, include #import include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('ticketing.urls')),# New 
]

If you look at terminal/cmd if the server is running you should see it complaining

  File "/home/symons/STICKETING/venv/lib/python3.6/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'ticketing.urls'

As you can see the error is too large I can’t copy and paste on Google, but at least a line makes sense

ModuleNotFoundError: No module named 'ticketing.urls'

so let’s create a module named URLs in ticketing folder

Create a new empty file named urls.py in the ticketing directory, and open it in the code editor.

django urls example

codes:

ticketing/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
]
  • in line 1: We are importing path
  • line 2: we are importing views
  • then line 3: we are defining URL patterns which are a list
  • lastly line 4:  inside ‘ ‘ we are defining what we expect after domain name in this case nothing, views.home means we are calling the home function from view module. name is what we will use to route internally in our site, eg in href= ….

If you check terminal again we have an error;

AttributeError: module ‘ticketing.views’ has no attribute ‘home’

True to the error in our views.py we don’t have a function/method called home.

ticketing/views.py

from django.shortcuts import render

def home(request):
    return render(request, 'home.html',{})
  • line 2: we are defining a function taking request as a parameter
  • line 3: we are returning request and HTML page that we want to be rendered

Error is gone but if you visit http://127.0.0.1:8000/ you will find another error

template does not exist in django

This is because we said we want user who requested the page to see home.html and it is not there.

FIX

Inside the app ticketing create another folder called templates. This is where Django will look for our HTML folders and files. Inside templates folder create a file called home.html

template structure

Content of home.html should be.

home.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>We Did It!</h1>
</body>

</html>

And we are set! fire up your server if it is not running yet

And that was all you needed to know about django app and its structure

$ python manage.py runserver

Have some coffee and let us meet in the next Chapter

Get the code from github

You may join my whatsapp group

or Contact me personally info@omborisymons.com

 

Write a comment