What is Django?
Django (read as, jang-goh) is a framework for web-application development. It is an open source framework written in Python. It makes website development faster, scalable and more secure.
What is a framework?
A token is a single element in programming language such as identifiers, keywords, operators, delimiters, and literals. We make a code statement by using tokens. We then structure our code in reuseable units like function and class. Functions and classes share the namespace of a program file also knwon as module. Modules are stored in folders callled packages. A bundle of these packages makes up a library. So a library is bunch of reuseable code that you may use in program to fill the gaps. A framework is similar to a library in terms of offering set of reuseable code packages.
In real-world conditions a library fills the gaps in your modules. But a framework acts a library inside-out. You fill the gaps in the framework to quickly and seamlessly develop your application.
So now its clear why Django is a framework. But what is a web-application then.
Website vs web-application
A website provides visual and text content which you can view without affecting its functioning. A web-application offers the features like a website and additionally let us interact with its functioning. A web-application usually requires user authentication and authorization.
For example, a website with about us, contact us and gallery pages is merely a website and it gives the same information to every user. On the other hand, web-applications like netbanking page, instagram etc. has more dynamic content rendered to you as per the context of your login information and query.
Django MVT
MVC is a software design pattern that has three components namely Model (back-end), View (front-end) and Controller. Django uses a modified version of MVC called MVT where:
Model is the data storage layer,
Template is the data presentation layer and
View is the logical layer that interacts with Model to fetch and render data to Template.
Request and response cycle in Django
A request starts when the user submits a URL in the web browser. The request is forwarded by middlewares to match a urlpattern. These urls path map to view functions or return error. A view function may take the request further to models to access data or directly render response to a template page.
Now you are ready to start your journey as Django full-stack developer. So let’s go to the next chapter about django versions, download and installation.
Download & Install Django
To get started with using Django framework you can select a LTS (Long Term Support) version of Django and simply install it using pip.
Django versions
As of June 2020 the recommended Django version to use is Django 2.2. It is a Long Term Support (LTS) version unlike Django 3.0 and Django 3.1. The next LTS release will be Django 3.2 in April, 2021.
Django Version | End of support |
---|---|
Django 2.2 LTS | April 2022 |
Django 3.0 | April, 2021 |
Pre-requisites to install Django
- Step 1: Install Python 3.5 or above from Python.org
- Step 2: Verify Python installation with python –version
- Step 3: Update Python package manage, pip python -m pip install –upgrade pip
Download Install Django on Windows 10
We do not need to download an exe or dmg version of django. Django is python package under PyPI(Python Package Index). We can install python packages under PyPI using the package manager called pip.
- Step 1: To install django with the pip run:pip install django==2.2
- Step 2: Verify django installation withdjango-admin –version
Install Django on Ubuntu or Mac OSx
Ubuntu or Mac OS might refer to python as python3. In this case we can do aliasing like alias python = /usr/bin/python3. We may sometimes need to install pip as well.
- To intall pip first run curl “https://bootstrap.pypa.io/get-pip.py” -o “get-pip.py”
- then follow it with python get-pip.py
- Lastly, to install django run pip install django==2.2, change version is required.
Install Django in Virtual Environment
Virtual environments can help maintain different software versions or django versions under the same operating system. It is recommended if there are many users for your computer who would like to work with different versions of python or django.
To install virtual environment simply, run:pip install virtualenv
To create a new virtual environment named myenv, run:virtualenv myenv
To start/activate virtual environment simply, run:myenv/Scripts/activate
To deactivate virtual environment, run:deactivate
Now you have installed Django 2.2. So let’s head to Django project and lauching server.
Django Start Project and App
Now that you have installed Django. It is time to start a new project and application.
Django Start Project
In any version of django you can start a new project with the below command:django-admin startproject project_name
The project directory will initially look like this:
project_name/ manage.py project_name/ __init__.py settings.py urls.py asgi.py wsgi.py
After this you may move to project directory. The outer folder with project name is merely a container housing you project, manage.py and the database.cd project_name
Django manage.py
manage.py helps manage you project by allowing you to run the command-line arguments same as django-admin.
Available subcommands:
[auth]
changepassword createsuperuser
[contenttypes]
remove_stale_contenttypes
[django]
check compilemessages createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata makemessages makemigrations migrate sendtestemail shell showmigrations sqlflush sqlmigrate sqlsequencereset squashmigrations startapp startproject test testserver
[sessions]
clearsessions
[staticfiles]
collectstatic findstatic runserver
Django migrate
migrate is used to apply migrations or publish changes. It is usually followed after makemigrations. The use of migrate here is to apply migrations for built-in apps like admin, auth, contentypes and sessions.python manage.py migrate
Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying sessions.0001_initial... OK
Django runserver
Now that our skeleton django project is ready we just need to run a local development server that comes built-in.python manage.py runserver

Now you have started a new django project, you can go next to staring django application.
Django Skeleton App
Django skeleton app is an app with only necessary and sufficient features to showcase the django reuqest response cycle. A simple Hello world text will be shown on the screen when the homepage is requested.
New Django Project & App
To get started with the skeleton project or the hello world project we must have python and django installed. Here is a quick recap of all pre-requisites: /p>
To install Django LTS version 2.2:
pip install django==2.2
To verify django version:
django-admin --version
To start new project:
django-admin startproject mysite cd mysite python manage.py migrate
To start new app
python manage.py startapp myapp
Below we have the code from each necessary module.
mysite : setting.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', ]
mysite : urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('myapp/', include('myapp.urls')) ]
myapp : urls.py
The urls.py module has to be created manually, under myapp directory.
from django.urls import path from . import views urlpatterns = [ path('', views.index) ]
myapp : views.py
from django.shortcuts import render def index(request): return render(request, 'index.html', {})
mysite : templates : index.html
The templates directory has to be created manually, under myapp directory. Then then index.html is also maually put under the templates directory.
Hello World
Django runserver
Finally, run the developent server and visit localhost on port 8000.
python manage.py runserver
And in you favourite web browser open url:
127.0.0.1:8000/myapp/
You may also download django skeleton app.
Django Models
Models are the data accees layer of your application. Every django application gets a models.py file by default to create database tables. The default database engine in django framework is sqlite3. It can be changed by visiting settings.py under project directory. Django uses ORM (Object Relational Mapping) that allows us to perform database operations without writing SQL queries but with simple python objects.from django.db import models
models is a module that packs the definitions for Model classes, different models fields and field relationships.
To create a table in simply make a class subclassing the Model class.class MyClassname(models.Model): …
Django Model Fields
Django version 2.2 offers 26 different field types to capture different data formats. For simplicity we have grouped them according to functionality rather than alphabetical sorting.
Django Models – Field Types
- AutoField
- BigAutoField
- UUIDField
- IntegerField
- PositiveIntegerField
- SmallIntegerField
- PositiveSmallIntegerField
- BigIntegerField
- DecimalField
- FloatField
- BinaryField
- BooleanField
- NullBooleanField
- CharField
- TextField
- EmailField
- SlugField
- URLField
- GenericIPAddressField
- DateField
- TimeField
- DateTimeField
- DurationField
- FileField
- FilePathField
- ImageField
Django Models – Field Options
The following arguments are available in Django field types:
- null
- blank
- choices
- db_column
- db_index
- db_tablespace
- default
- editable
- error_messages
- help_text
- primary_key
- unique
- unique_for_date
- unique_for_month
- unique_for_year
- verbose_name
- validators
Django Models – Field Relationships
Sometimes business logic require relationships among attributes of different model classes. Their are three field relationships in django models: ForeignKey(), OneToOneField() and ManyToManyField().
Django ForeignKey
ForeignKey is like a many-to-one relationship. It requires two positional arguments namely Classname and on_delete.
Classname is the class to which model is related.
on_delete=models.CASCADE means when the Super class object is deleted all its reflections as ForeignKey also gets deleted. For example when the Customer object in below model is deleted it’s related Order objects are also deleted.
class Customer(models.Model): name = models.CharField(max_length=30) def __str__(self): return self.name class Order(models.Model): customer = models.ForeignKey(Customer, on_delete=models.CASCADE) order_details = models.TextField()
Django OneToOneField
OneToOneField is very similar to ForeignKey except the realtionship is like unique=True.
For example, if one Person can be have only one nationality it can described as below:
class Person(models.Model): name = models.CharField(max_length=30) def __str__(self): return self.name class Citizenship(models.Model): person = models.OneToOneKey(Person, on_delete=models.CASCADE) country = models.CharField(max_length=30)
Django ManyToManyField
A many-to-many relationship requires only one argument i.e, the class to which the model is related. It can be understood with the example below:
class Person(models.Model): name = models.CharField(max_length=30) class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through='Membership', through_fields=('group', 'person'), ) class Membership(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) person = models.ForeignKey(Person, on_delete=models.CASCADE) inviter = models.ForeignKey( Person, on_delete=models.CASCADE, related_name="membership_invites", ) invite_reason = models.CharField(max_length=64)
Now you have learnt about django models and can proceed to the next lesson.
Django Import Export Library
django-import-export library provides an import_export app for your django project. You can use the import_export app with Django Admin. It will simpy add fully functional import and export buttons to admin dashboard.
Model data can be imported from csv, xml, excel, json etc. You may also export data to multiple file formats like csv, xls, xlsx, tsv, ods, json, yaml and html.
You may easily add the import export app in 4 easy steps:
- Step 1: Install django-import-export via pip
- Step 2: Add import_export to INSTALLED_APPS in settings.py
- Step 3: Import and inherit ImportExportModelAdmin in admin.py
- Step 4: Set import_export app permissions under settings.py (if needed)
Installing django-import-export library
To install django-import-export library simply run:pip install django-import-export
Add import_export app to the project settings.py
Now, you must add import_export app in your project settings.py under the INSTALLED_APPS attribute list. Notice that the “-” is replaced with “_” because of Python’s nomenclature rules.
INSTALLED_APPS = [ ... 'import_export', ]
Sample Project of Django Import Export
[Note: Complete project is at the end of the page for free download.]
We are going to use an example model class called Blog under myapp
models.py
from django.db import models class Blog(models.Model): title = models.CharField(max_length=120) author = models.CharField(max_length=120) date_of_publishing = models.DateField(auto_now_add=True) content = models.TextField() def __str__(self): return self.title
Now, simply import and inherit ImportExportModelAdmin class in admin.py
admin.py
from import_export.admin import ImportExportModelAdmin from django.contrib import admin from .models import Blog class BlogAdmin(ImportExportModelAdmin, admin.ModelAdmin): ... admin.site.register(Blog, BlogAdmin)
Note: ImportExportModelAdmin should be prior to admin.ModelAdmin in the multiple inheritance sequence to avoid MRO (Method Resolution Order) error.
Importing
Exporting
Django import_export app permissions
With above code all staff users will have access to django import export feature under Admin interface. In order to restrict access to user with add, view, change or delete permissions, add the code below in project settings.py.IMPORT_EXPORT_IMPORT_PERMISSION_CODE = ‘delete’ IMPORT_EXPORT_EXPORT_PERMISSION_CODE = ‘delete’
In place of delete you may use other permissions like “add”, “view” or “change”.
Try is yourself: download sample django-import-export project.
Django Admin
Django Admin is a backend user interface for web-application super user and staff users. You can register you models in admin site and can control create, view, change and delete activities in models. A superuser can be created first with createsuperuser command and then the other users can be created from Admin interface.
Django Admin – Users & Groups
To create your first user as superuser run:python manage.py createsuperuser
It will then ask to input below fields and confirm Superuser created successfully.
Username : Email address: Password: Password (again):
You may visit the admin page with below url (if development server is running):
You can then use the aforementioned login credentials in the Django Administration page. Other Users and authentication Groups can be created with Admin interface.
Register Model with Django Admin
To register models with admin interface simply add below statement in admin.py module. Here Blog is an example of Model name.
from django.contrib import admin from .models import Blog admin.site.register(Blog)
Django Admin Options
Django admin can offer a dashboard with many options to view and manage model data. Below are some admin options and their implications.
- list_display: It can display list of each record in given order.
- list_filter: It can add filters to model with mentioned fields
- fields: It is used to organise detail view layout.
- fieldsets: It is used for sectioning the detail view.
- list_editable: It makes mention fields available for quick editing.
- search_fields: It searches the query in mentioned model fields only.
- exclude: It is the negative list of elements to be excluded from admin console display.
- ordering: It defines the tuple for ordering model data.
- list_per_page: It can be used for pagination. Example: 25 rows per page
- radio_fields: It can convert select fields or dropdown fields to radio fields.
Now you have learnt about django admin and admin options, let’s go to Django models.
Django urls and views
A request in django first comes to urls.py and then goes to the matching function in views.py. Python functions in views.py takes the web request from urls.py and gives the web response to templates. It may go to the data access layer in models.py as per the queryset.

If we look at the 3-tier architecture of an app. Views are like the business logic layer. It is the controller in a typical MVC (Model View Controller) design but django has a slighly differnt naming convention called MVT (Model View Template) where:
Model is the data access layer,
View is the business logic layer and
Template is the presentation layer.

Django Urls Path
Django has a urls.py file under the project by default. It also has a prep-defined path for admin app. However, django recommends mapping all resources via another urls.py newly created under the app. The below explains it:
mysite — urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('myapp/', include('myapp.urls')), ]
myapp — urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index), # app homepage ]
Django View Function
The url mapping will redirect request from project urls to app urls and then to the respective view function. A sample view function code may look like this:
def index(request): return render(request, 'index.html', {}) or, from django.http import HttpResponse def index(request): return HttpResponse("Hello World")
Here, request is the url request mapping and calling the view function. render combines a given template with a given context dictionary. {} denotes the dictionary of values that can be added to the template context.
Django ORM and QuerySets
Django simplifies the task of interacting with the databases by using ORM (Object Relational Mapper). You can write universal database queries with simple QuerySets.
Whaht is QuerySet
A Queryset is simply a list of objects from the Django Models. It can be used to query data as Create, Filter, Update, Order etc. Queryset can be written in Django Shell or in views.py.python manage.py shell
For example, to get all data from the model Blog under app named myapp, run:
>>> from myapp.models import Blog >>> Post.objects.all() QuerySet ['my blog title', ...]
Popular Django QuerySets
Create
ModelName.objects.create(fieldname=value)
Select
ModelName.objects.all()
Filter
ModelName.objects.filter(fieldname=value)
Exclude
ModelName.objects.exclude(fieldname=value)
Ordering
ModelName.objects.all().order_by(‘field_name’)
Django Forms
Django Forms can be used to move data in or out from models. An alternative to this is ModelAdmin but it is recommended to be used by the superuser or staff users only. An end-user of your web app must submit data from forms in template pages. We can choose to create fields in the form using HTML or ModelForm. In both cases we begin by creating a new file named forms.py under our app directory.
mysite └── ... myapp └── ... └── forms.py
Django ModelForm
Similar to ModelAdmin we can use the ModelForm class and make a form object linking to the fields defined under models.py
forms.py
from django import forms from .models import Blog class BlogForm(forms.ModelForm): class Meta: model = Blog fields = '__all__'
__all__ includes all fields under the model class. You may alternatively use a tuple of field names.
Now this ModelForm object will be used under views.py as below:
views.py
from django.shortcuts import render, redirect from .forms import BlogForm def my_view_function(request): form = BlogForm(request.POST or None) if form.is_valid(): form.save() return redirect('/mypageurl/') return render(request, 'my_template_page.html', {'form':form})
- redirect: This function can redirect request object to the given url path.
- request.POST: It will submit data posted in html form elements.
- is_valid(): This function validates the form data against model field types and options.
- save(): This function saves the data in the database.
Lastly, we are required to make a form element in our template page as below:
templates — my_template_page.html
{% csrf_token %} {{ from.as_p }}
- method=”POST”: It refers to the Http POST request. The default is GET.
- csrf_token: It is a security token to prevent against Cross site reference forgery.
- The form requires an submit button apart from model field elements, to trigger form submisison.
Django Templates & Static files
Django templates are the presentation layer of django web-application. A templates folder is typically created under the app directory and it has .html files. A static directory can also be created under the app directory to store images, css and js files.
mysite └── ... myapp └── templates └── index.html └── static └── img └── css └── js
Django Template Tags
Django templates is a mix of static html markups and dynamic python context dictionary. Sereval template tags and filters are available to render the context dictionary.
Template Tags
- {% extends ‘base.html’ %}: It extends the code of base template to any template file that sub-classes it. extends tag must be the first line if used.
- {% block content %}: It marks the dynamic section of a template which will be described in the extending template.
- {% load static %}: It load the static resources under static directory.
- {% for loop %}: It impliments a simple python for loop.
- {% if condition %}: It impliments a simple python if condition.
- {# comment #}: It is used for comments other than HTML comments.
- {{ variable }}: It print the value of the given variable. A newline is not automatically included unlike Python print statement. Although html br tag can serve the same purpose.
Template Filters
Filters can be used to enhance the value of context key variable.
{{ value|filter }}
All available filters in django templates are as follows:
- add
- addslashes
- capfirst
- center
- cut
- date
- default
- default_if_none
- dictsort
- dictsortreversed
- divisibleby
- escape
- escapejs
- filesizeformat
- first
- floatformat
- force_escape
- get_digit
- iriencode
- join
- json_script
- last
- length
- length_is
- linebreaks
- linebreaksbr
- linenumbers
- ljust
- lower
- make_list
- phone2numeric
- pluralize
- pprint
- random
- rjust
- safe
- safeseq
- slice
- slugify
- stringformat
- striptags
- time
- timesince
- timeuntil
- title
- truncatechars
- truncatechars_html
- truncatewords
- truncatewords_html
- unordered_list
- upper
- urlencode
- urlize
- urlizetrunc
- wordcount
- wordwrap
- yesno
Static files
Django project settings.py defines a static directory that typically houses images, css and javascript files. A sample code below is shows how to use the static files.
{% load static %}
In img tag use:
src="{% static 'img/my_image.png' %}"
For CSS files use under link tag:
href="{% static 'css/my_stylesheet.css' %}"
For Javascript files use under script tag:
src="{% static 'js/my_script.js' %}"Django AuthenticationDjango auth app allows us to login a user and control what they can do within our webapp.Django has a built in User model with fields like first_name, last_name, email, username, password etc. We can use the built-in user model or extend it by making another model that has one OneToOneField relationship with User model.Django Auth ExampleThis tutorial uses the built-in User model and authenticate, login and logout methods from django.contrib.auth app.django.contrib.auth is a built-in app which is also already listed under settings.py. Below is module wise code that follows for creation of user registration, login and logout sessions.models.py from django.db import models from django.contrib.auth.models import User app > urls.py from django.urls import path from . import views urlpatterns = [ path('', views.index), path('login/', views.signin), path('logout/', views.signout), path('signup/', views.signup), ] forms.py from django.contrib.auth.models import User from django import forms class UserForm(forms.ModelForm): class Meta: model = User fields = ['username', 'password'] class UserRegistrationForm(forms.ModelForm): class Meta: model = User fields = [ 'username', 'password', 'email', 'first_name', 'last_name' ] Registration, Login and Logoutviews.py from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.contrib.auth import authenticate, login, logout from .forms import UserForm, UserRegistrationForm from django.http import HttpResponse from django.contrib.auth.models import User @login_required def index(request): return render(request, 'index.html', {}) def signin(request): if request.method == "POST": username = request.POST['username'] password = request.POST['password'] user = authenticate( request, username=username, password=password ) if user is None: return HttpResponse("Invalid credentials.") login(request, user) return redirect('/') else: form = UserForm() return render(request, 'login.html', {'form':form}) def signout(request): logout(request) return redirect('/') def signup(request): if request.method=="POST": first_name = request.POST['first_name'] last_name = request.POST['last_name'] username = request.POST['username'] password = request.POST['password'] email = request.POST['email'] newuser = User.objects.create_user( first_name=first_name, last_name=last_name, username=username, password=password, email=email ) try: newuser.save() except: return HttpResponse("Something went wrong.") else: form = UserRegistrationForm() return render(request, 'signup.html', {'form':form}) @login_required decoratorlogin_required decorator allows us to redirect any url request to a pre-defined LOGIN_URL under settings.py LOGIN_URL = '/login/'