3. Introduction to Django
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● It is a web framework for developing scalable, secure and maintainable applications.
● It is based on MVC pattern with a slight difference in naming. The view is referred as template
and controller is referred as view in Django so it is MTV.
● It officially supports following databases – PostgreSQL, MySQL, SQLite, Oracle.
● It helps in faster developments.
● It is written on the powerful language Python.
● It can be used for high load projects. For eg, Instagram and Pinterest.
8. Models
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● It contains the essential fields and behaviors of the data.
● Each model is a Python class and also a sub-class of django.db.models.Model
● Each model represents a table in the database.
● Each field represents a column in the table.
● Each field has a field type which can be any of the following.
- CharField, TextField
- IntegerField, FloatField, DecimalField
- DateField , TimeField, DateTimeField
- EmailField, URLField
- ForeignKey, ManyToManyField and many more.
9. Create Model
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Blog Model Example,
from django.db import models
class Blog(models.Model):
status_choices = (
(‘D’, ‘Draft’),
(‘P’, ‘Published’)
)
title = models.CharField(max_length=100)
description = models.TextField()
status = models.CharField(max_length=1, choices = status_choices)
def __str__(self):
return self.title
10. Migrations
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Migrations are how Django stores changes made to the database schema/models.
● The migration files can be found inside migrations directory in your app directory.
● Following command tells Django that you made changes to your models
python manage.py makemigrations {appname}
● Following command take latest migration file and updates database
python manage.py migrate {appname}
11. Create Model Instance
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Run Python Interactive Shell
python manage.py shell
● Import model. For eg,
from myapp.models import Blog
● Create new Blog object. For eg,
b1 = Blog(…)
b1.save()
12. Query Data From DB
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Run Python Interactive Shell
python manage.py shell
● Import model. For eg,
from myapp.models import Blog
● Get all from DB. For eg,
all_blogs = Blog.objects.all()
● Objects is the manager. The manager takes care of all table level operations including data
lookup.
14. Data Lookup: get()
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Get() returns a single object.
● For eg,
blog_with_id = Blog.objects.get(id=‘2’)
● Exception incase of multiple objects returned. For eg,
blog_multiple_results = Blog.objects.get(title__contains=‘some text’)
● Exception incase no results found. For eg,
blog_no_results = Blog.objects.get(title=‘some text’)
15. Data Lookup: order-by()
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● We can get the resulting QuerySet in a specific order.
● Order-by title. For eg,
blog_by_title = Blog.objects.order_by(‘title’)
● Reverse order-by title. For eg,
blog_by_title = Blog.objects.order_by(‘-title’)
● Add default order-by in model. For eg,
class Blog(models.Model);
------------------------
class Meta:
ordering = [‘-id’]
16. Chaining & Slicing
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● We can chain multiple lookups to get required data.
● For eg,
blog_chain_lookup = Blog.objects.filter(title__contains=“Blog”).order_by(“title”)
● We use slicing to get limited number of result.
● For eg,
blog_first = Blog.objects.all()[0]
blog_first_five = Blog.objects.all()[0:5]
blog_last = Blog.objects.order_by(‘-id’)[0]
17. Update Data
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Method 1:
blog = Blog.objects.get(id=1)
blog.title = “Updated Title Blog 1”
blog.save()
● Method 2 (Better Performance):
Blog.objects.filter(id=1).update(title=“Updated Title Blog 1”)
● Update multiple row:
Blog.objects.filter(status=‘D’).update(status=‘P’)
18. Delete Data
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● To delete data we can simple call delete().
● For eg,
blog = Blog.objects.get(id=3)
blog.delete()
● We can also delete multiple rows. For eg,
Blog.objects.filter(status=‘D’).delete()
● We can also delete all rows. For eg,
Blog.objects.all().delete()
20. Views
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● View is the Business Logic Layer.
● It fetches data from your database and delivers it to a template.
● It decides what data needs to be sent to the templates.
● It handles the data received by user interactions and internal processes.
● Each view handles a specific function.
● A view can either be a Python function or a class.
21. Writing Our First View
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Below are some function based view.
from django.http import HttpResponse
def index(request): // prints “Hello World” on the browser
return HttpResponse(“Hello World”)
def details(request, id): prints blog object label for the given id
blog = Blog.objects.get(id=id)
return HttpResponse(blog)
22. Mapping our first URL
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● URLConf
from django.conf.urls import url
from blogapp.views import index
urlpatterns = [
….
url(r'^$', index),
url(r’^details/(?P<id>[-w]+)/$)’, details),
url(r’^review/(?P<year>[0-9]{4})/(?P<mon>[0-9]{2})/$’, reviews)
]
● For eg,
“details/1/” => details(request, id=1)
“reviews/2018/08/” => reviews(request, year=2018, mon=08)
24. Templates
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● This is the display logic layer.
● It separates application data from the way it is presented.
● These are mostly HTML files for presenting application data in web browser.
● The HTML template holds template tags to populate the data passed from views.
25. Writing our first Template
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Create a directory /templates
● Create a file “index.html”
● Add following code in it:
<html>
<head><title>First Django Template</title></head>
<body>
<h1>Welcome {{ name }}</h1>
</body>
</html>
Note: The value for template variable {{ name }} is passed from view
26. Writing View For The Previous Template
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Add the following view:
from django.shortcuts import render
def welcome(request):
context = {
“name”: “Qaifi Khan”
}
return render(request, “index.html”, context)
● Visit settings.py and add the templates directory:
TEMPLATES = [
{
'DIRS': ['templates’],
}
]
27. Some Template Tags: If-elif
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
{% if age_more_than_18 and age_less_than_28%}
<p>Age 18-28</p>
{% elif age_less_than_38 or age_more_than_48%}
<p>Age 28-38 or more than 48</p>
{% elif not eligible %}
<p>Not eligible</p>
{% elif “xy” in “wxyz” %}
<p>In wxyz</p>
{% else %}
<p>Else</p>
{% endif %}
28. Some Template Tags: for
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
<ul>
{% for blog in blog_list reversed %}
<li>{{ forloop.counter }} : {{ blog.title }}</li>
{% empty %}
<p>No blogs found</p>
{% endfor %}
</ul>
//forloop.counter starts with 1
//forloop.counter0 starts with 0
//forloop.revcounter starts with last but is 1-indexed
//forloop.revcounter0 starts with last but is 0-indexed
30. Admin Site
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Django provides a built-in admin panel.
● You can perform all CRUD operations on your database.
● We can control which models are accessible from Admin panel.
● To access admin panel we need to create a super user.
● Follow these steps to create a super user.
- In command prompt type “python manage.py createsuperuser”
- Enter username, email, password and confirm password.
- Start development server again and visit admin panel
- Input login credentials and login
31. Adding a Model for Access in Admin Panel
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Open admin.py in the application directory
● Add the following code:
from .models import {model_name}
admin.site.register(model_name)
32. Showing More Data in List Display
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● You can control the fields visible in list display section.
● For that we need to create a ModelAdmin. Let’s do that.
class BlogAdmin(admin.ModelAdmin):
list_display = (‘title’, ‘status’)
……
admin.site.register(Admin, BlogAdmin)
33. Adding a Search Bar
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● To add a search bar we need to Edit the ModelAdmin.
● Make following changes
class BlogAdmin(admin.ModelAdmin):
list_display = (‘title’, ‘status’)
search_fields = (‘title’)
……
admin.site.register(Admin, BlogAdmin)
34. Adding Filters
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● To add filter functionality we need to Edit the ModelAdmin.
● Make following changes
class BlogAdmin(admin.ModelAdmin):
list_display = (‘title’, ‘status’)
search_fields = (‘title’,)
list_filter = (‘status’,)
……
admin.site.register(Admin, BlogAdmin)
35. Customizing Edit Form
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● We can also customize the Edit Form.
● To specify what all fields are editable, pass a list in fields as shown below.
class BlogAdmin(admin.ModelAdmin):
list_display = (‘title’, ‘status’)
search_fields = (‘title’,)
list_filter = (‘status’)
fields = (‘title’, ‘description’)
……
admin.site.register(Admin, BlogAdmin)
37. Let’s Create a Basic Form GET Request
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Create HTML form:
<form action=‘/search/’ method=“get”>
<input type=“text” placeholder=“Enter Search String” name=“q”/>
<input type=“submit” value=“Search” />
</form>
● Create request URL:
url(r’^search/$’, search)
38. Basic Form GET Request Continued…
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Handling at View:
def search(request):
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.’
return HttpResponse(message)
39. Using Django’s Form Class
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Django provides us with a “Form” library to manage everything from form display to validation.
● We need to define one form class for each HTML form required by us. So let’s start.
● Create a new file form.py. Add following code:
from django import forms
STATUS_CHOICES = ((‘D’, ‘Draft’), (‘P’, ‘Published’))
class CreatePostForm(forms.Form):
title = forms.CharField()
description = forms.CharField(widget=forms.Textarea())
status = form.ChoiceField(widget=forms.Select(), choices= STATUS_CHOICES)
40. Using Django’s Form Class Continued…
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Add following in view.py
from blogapp.forms import CreatePostForm
def create_post(request):
if request.method == ‘POST’:
form = CreatePostForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
blog = Blog(title = cd[‘title’],
description = cd[‘descripition’],
status = cd[‘status’])
else:
form = CreatePostForm()
return render(request, ‘create_post.html’, {‘form’: form})
41. Adding Validation
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Make following changes in CreatePostForm class:
from django import forms
STATUS_CHOICES = ((‘D’, ‘Draft’), (‘P’, ‘Published’))
class CreatePostForm(forms.Form):
title = forms.CharField(max_length=100, required=True)
description = forms.CharField(widget=forms.Textarea() , required=True)
status = form.ChoiceField(widget=forms.Select(), choices= STATUS_CHOICES)
42. Adding Custom Validation
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Make following changes in CreatePostForm class:
class CreatePostForm(forms.Form):
…..
def clean_description(self):
description = self.cleaned_data[‘description’]
num_words = len(description.split(‘ ‘))
if num_words < 3:
raise forms.ValidationError("Not enough words!")
return description
● Note: Django automatically call any method starting with “clean_” during validation.
43. Model Forms
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Sometime we just need a form for a predefined model. In that case we can simply use
ModelForm. Let’s start.
● Add following code in forms.py
from django.forms import ModelForm
from .models import Blog
class CreateBlogModelForm(ModelForm):
class Meta:
model = Blog
fields = [‘title’, ‘description’]
//exclude = [‘status’]
44. Overriding Labels, HelpText, Widgets, HelpText etc in ModelForm
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Make following changes in the code:
class CreateBlogModelForm(ModelForm):
class Meta:
……
labels = {
‘title’: ‘Blog Title’,
‘description’: ‘Blog Description’}
widgets = {
description: Textarea()}
45. Adding Custom Validation in ModelForm
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Make following changes in CreatePostForm class:
class CreateBlogModelForm(ModelForm):
def clean_description(self):
description = self.cleaned_data[‘description’]
num_words = len(description.split(‘ ‘))
if num_words < 3:
raise forms.ValidationError("Not enough words!")
return description
class Meta:
……..
● Note: Django automatically call any method starting with “clean_” during validation.
46. Upload an Image
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Configure MEDIA_ROOT and MEDIA_URL in settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, '/media/’) //Path where file stores
MEDIA_URL = '/media/’ //Browser URL to access file
● Configure MEDIA_ROOT and MEDIA_URL in settings.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
……
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
47. Upload an Image Continued…
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Make following changes in forms.py
class CreatePostForm(forms.Form):
……
image = forms.FileField()
● Make following changes in views.py
def create_post(request):
form = CreatePostForm(request.POST, request.FILES)
Blog(image = cleaned_data[‘image’])
● Make following changes in HTML file
<….. enctype="multipart/form-data">
49. Settings
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Django provides with a default settings file.
● We can create our own settings file as well.
● In case there are multiple settings file, we need to tell Django which file to use. For this we can
use the environment variable DJANGO_SETTINGS_MODULE.
export/set DJANGO_SETTINGS_MODULE=myproj.settings
● We can use settings variables in our code as well. For eg,
from django.conf import settings
if settings.DEBUG:
………..
50. Exceptions
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Django raises some of its own exceptions as well as standard Python exceptions.
● Some Django exceptions are:
● ObjectDoesNotExist: raised when object not found for a query.
● FieldDoesNotExist: raised when a requested field doesn’t exist.
● MultipleObjectsReturned: raised when query returns multiple object but only one was expected.
● ViewDoesNotExist: raised when requested view doesn’t exist for a url.
● FieldError: raised when there is a problem with a model field.
● ValidationError: raised when data is not what was expected in the form.
And many more…
51. Django-admin and manage.py
support@zekeLabs.com | www.zekeLabs.com | +91 8095465880
● Both perform the same task except manage.py sets DJANGO_SETTINGS_MODULE
environment variable to the project’s settings file.
● Syntax:
django-admin <command> [options]
manage.py <command> [options]
● For eg,
django-admin makemigrations {app_name}
django-admin migrate {app_name}
django-admin runserver
django-admin shell