A comprehensive introduction to Python Django
Django is a very powerful Python Web development framework designed for “rapid development” and “clean, functional design”. This article will start with the basic concepts of Django and lead you to understand how to use Django to build complex web applications.
Django Basic Concepts and Principles
First, let’s start with Django’s core components. Django follows the MVC Model-View-Controller design pattern and has a special manifestation in Python called MTV Model-Template-View. This is because the controller part of Django is handled internally by the framework itself, while the developer primarily interacts with models, templates, and views.
# Sample code:CreateDjangoModel
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def __str__(self):
return self.title
In the above code, we defined a simple blog model with two fields, title and content. Where CharField
and TextField
are the database field types provided by Django.
View and URL configuration for Django
In Django, views are Python functions that receive Web requests and return Web responses. Each view function takes an HttpRequest object as a parameter and returns an HttpResponse object. The view is associated with the URLs of the Web application, and this is done through the URL configuration.
# Sample code:Create a view
from django.http import HttpResponse
from .models import Blog
def blog_index(request):
blogs = Blog.objects.all()
output = ', '.join([blog.title for blog in blogs])
return HttpResponse(output)
# Sample code:URLConfiguration
from django.urls import path
from . import views
urlpatterns = [
path('blogs/', views.blog_index, name='blog_index'),
]
In the above code, we first define a view blog_index
that fetches all blog entries from the database and displays their titles. We then create a new URL path’blogs/ ‘in the URL configuration to associate it with the blog_index
view.
Django templates
Django’s template system allows us to create dynamic HTML pages. Django templates use their own language and are a small subset of Python.
<!-- Sample code:Create a template -->
{% for blog in blogs %}
<h2>{{ blog.title }}</h2>
<p>{{ blog.content }}</p>
{% endfor %}
In the above code, we created a template that receives a list of blog objects and generates an HTML paragraph for each object.
Django Middleware
Django also has a very powerful feature called middleware. Django’s middleware is a lightweight, low-level “plug-in” system for globally changing Django’s input or output.
The following is an example showing how to create a simple middleware that records the processing time of each request.
# Sample code:Create a middleware
import time
from django.http import HttpResponse
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start_time = time.time()
response = self.get_response(request)
end_time = time.time()
response['X-Elapsed-Time'] = str(end_time - start_time)
return response
In the above code, we created a TimingMiddleware
middleware that calculates the processing time of the request on each request and adds a X-Elapsed-Time
field in the HTTP response header to display this time.
Database Migration for Django
Database migration is a very powerful feature in Django that allows us to change the structure of the database without losing data. Let’s look at an example.
# existmodels.pymiddle,we willBlogThe model is modified as follows:
class Blog(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.CharField(max_length=100) #New fields
def __str__(self):
return self.title
In the above code, we added a author
new field to the Blog model. To apply this change to the database, we need to do a database migration.
# Run the following command to generate the migration file
python manage.py makemigrations
# Run the following command to apply the migration
python manage.py migrate
With the above command, Django automatically adds a new field to the database for the Blog model, rather than requiring us to manually modify the database.
Django Forms and Validation
Django’s form functionality makes it easier for us to receive and process user data. At the same time, Django also provides a variety of verification functions to help us verify the validity of user data.
# Sample code:Create a form
from django import forms
from .models import Blog
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = ['title', 'content', 'author']
# Use forms in views
def new_blog(request):
if request.method == 'POST':
form = BlogForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse('Blog saved.')
else:
form = BlogForm()
return render(request, 'new_blog.html', {'form': form})
In the above code, we created a form based on the Blog model and then used the form in the new_blog
view. When the view receives a POST request, it validates the form data and, if the data is valid, saves the new blog and returns a response.
Django Rest Framework (DRF)
The Django Rest Framework is a powerful tool for building Web APIs. Using DRF, we can quickly create RESTful APIs.
# Sample code:CreateAPIview
from rest_framework import generics
from .models import Blog
from .serializers import BlogSerializer
class BlogListCreate(generic.ListCreateAPIView):
queryset = Blog.objects.all()
serializer_class = BlogSerializer
In the above code, we use the DRF’s ListCreateAPIView
view, which handles GET and POST requests. We need to provide one queryset
and one serializer_class
, and the DRF automatically handles the request and the response.
One More Thing
Finally, we’ll cover Django’s Signals. Signals are an event-driven mechanism in Django that sends a signal when something happens, and we can write receivers to listen for these signals.
# Sample code:Create a signal receiver
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Blog
@receiver(post_save, sender=Blog)
def notify_admin(sender, instance, created, **kwargs):
if created:
print(f'New blog created: {instance.title}')
In the above code, we have created a receiver notify_admin
that will be called each time a new Blog object is created. Signals allow us to write decoupled code, making our applications easier to maintain and extend.