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:
-
- Model: Model component is responsible for the application data, this may be a database, file or an object it also takes some logics
- 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.
- 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
Now ticketing is our app. Lets open STICKETING folder with a text editor of your choice, I will use Vscode.
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
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:
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.
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
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
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