Django Views Deeper: Mastering advanced features and optimization techniques
Hello, fellow Django developers! Today we'll be discussing Defaultfollowed by the Django You're familiar with basic functional views, but now it's time to take it to the next level and use Views more efficiently and make your projects more powerful. Are you ready to take your Django skills to the next level? Let's get started!
Django Views in depth - Class-based views (CBV)
Class-Based Views (CBV) is a feature provided by the Python-Django web development framework that allows you to implement the functionality of your web pages in the form of classes, making your code more reusable and easier to structure. CBVs have the following advantages over function-based views (FBVs)
Pros
- Offers a wide range of featuresCBV has pre-implemented a variety of features such as List, Detail, Create, Modify, Delete, and more through Generic Views, so developers can simply inherit the features they need.
- Code reusabilityCBV allows you to reuse code through inheritance. For example, a list page and a detail page have a lot of similar functionality, and CBV allows you to simplify your code by defining the common parts in a parent class and adding only the functionality you need on each page.
- Structuring your codeCBV makes it easy to structure your code by dividing classes by functionality. This makes the code easier to understand and maintain.
Let's take a look at a simple example.
from django.views import View
from django.http import HttpResponse
class HelloView(View):
View. def get(self, request):
return HttpResponse("Hello, it's a class-based view!")Code description
1.
from django.views import View
- Django's
viewsIn the moduleViewGet the class.ViewClasses are the basic classes that you inherit when you create a class-based view (CBV).2.
from django.http import HttpResponse
- Django's
httpIn the moduleHttpResponseGet the class.HttpResponseclass is used when generating HTTP responses.3.
class HelloView(View):
HelloViewDefine a class named- This class implements the
Viewclass inherits from.- That is,
HelloViewwill be a class-based view.4.
def get(self, request):
HelloViewInside the classget.getmethod is responsible for handling HTTP GET requests.requestis the object that holds the request information from the client.5.
return HttpResponse("Hello, it's a class-based view!")
HttpResponseobject and pass it the string "Hi, it's a class-based view!" as an argument.- This string is put in the body of the HTTP response and sent to the client.
returnstatement is aHttpResponseobject.
To link this view to a URL, do this: When "homepage address/hello/" is typed into the browser address bar, HellowView will work.
path('hello/', HelloView.as_view(), name='hello'), # Connect HelloView to the URL 'hello/' and give it the name 'hello'The beauty of class-based views is that they can easily be handled per HTTP method.
class MyView(View):
def get(self, request):
# Handle a GET request
return HttpResponse("This is a GET request")
def post(self, request):
# Handle a POST request
return HttpResponse("This is a POST request")Code commentary
1.
class MyView(View):
MyViewDefine a class named- This class implements Django's
Viewclass inherits from.- That is,
MyViewbecomes a Class-Based View (CBV).2.
def get(self, request):
MyViewInside the classget.getmethod is responsible for handling HTTP GET requests.- When a client accesses a web page, the web browser sends a GET request to the server.
requestis the object that holds the request information from the client.3.
# GET request processing:
- An annotation. They are used to describe the functionality of your code.
4.
return HttpResponse("This is a GET request")
HttpResponseobject and pass it the string "This is a GET request" as an argument.- This string is put in the body of the HTTP response and sent to the client.
returnstatement is aHttpResponseobject.5.
def post(self, request):
MyViewInside the classpostmethod calledpostmethod is responsible for handling HTTP POST requests.- When a client submits form data to a server, the web browser sends a POST request to the server.
requestis the object that holds the request information from the client.6.
# POST request processing:
- An annotation. They are used to describe the functionality of your code.
7.
return HttpResponse("This is a POST request")
HttpResponseobject and pass it the string "This is a POST request" as an argument.- This string is put in the body of the HTTP response and sent to the client.
returnstatement is aHttpResponseobject.
Django Views Deeper - Utilizing Generic Views
Django provides Generic Views, which are pre-built implementations of commonly used patterns in web development. Using Generic Views can help you reduce repetitive code writing and improve development productivity by making your code more readable.
Benefits of generic views
- Code reusabilityGeneric views pre-implement commonly used features, so developers can simply inherit the functionality they need.
- Code conciseness: Generic views reduce repetitive code, so you can write more concise code.
- Code readability: Generic views separate classes by functionality, making the code easier to understand and maintain.
Major generic view types

DeleteViewView that provides the ability to delete objects
ListView: View showing a list of objects
DetailViewView showing details of a specific object
CreateView: A view that provides a form for creating objects
UpdateViewViews that provide forms for modifying objects
For example, if you want to create a view that shows a list of objects, you can do this. With this simple code, you can create a view that shows a list of all the objects in the Book model.
from django.views.generic import ListView
from .models import Book
class BookListView(ListView):
model = Book
template_name = 'book_list.html'
context_object_name = 'books'Code commentary
1.
from django.views.generic import ListView
- Django's
views.genericIn the moduleListViewGet the class.ListViewis a generic view that is useful for creating web pages that show a list of multiple objects.2.
from .models import Book
- The current application's
modelsIn the moduleBookImport the model.BookA model is a class that defines the book information to be stored in the database.3.
class BookListView(ListView):
BookListViewDefine a class named- This class implements the
ListViewclass inherits from.- That is,
BookListViewTheListViewto create a book listing page.4.
model = Book
modelattribute is aListViewspecifies the model to use.- Here, we'll use the
BookNow that you've specified a model,BookListViewTheBookCreate a page showing a list of books stored in the model.5.
template_name = 'book_list.html'
template_nameproperty specifies the name of the template file.- Here, we'll use the
book_list.htmlUse the file as a template to organize your book listing page.- This template file is called
BookServes to display a list of objects in the model in HTML format.6.
context_object_name = 'books'
context_object_nameproperty specifies the name of the list of objects to use in the template.- By default, the
ListViewTheobject_listto the template as a list of objects.- However, the
context_object_nameto change it to the name of your choice.- Here, we'll use the
booksto the template, so the template will pass a list of objects with the name{{ books }}to access the list of books in the same way.
Django Views Deeper - Using Mixins
Mixins are a useful tool for reusing code and extending functionality in class-based views (CBVs). A mixin is a small piece of class that performs a specific function and can be mixed in with other classes.
Benefits of mixins
- Code reusability: Mixins allow common functionality to be reused across multiple classes, reducing code duplication and improving maintainability.
- Code readability: Separating functionality into mixins makes it easier to see what a class does, making your code more readable.
- Flexibility: You can easily create classes with a wide range of functionality by combining mixins that have the functionality you need.
Mixins make it easy to add additional functionality to your views. For example, if you want to create a view that requires a login, you can do something like this: This view is only accessible to logged-in users.
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import DetailView
from .models import PrivateDocument
class PrivateDocumentView(LoginRequiredMixin, DetailView):
model = PrivateDocument
template_name = 'private_document.html'Code commentary
1.
from django.contrib.auth.mixins import LoginRequiredMixin
- Django's
contrib.auth.mixinsIn the moduleLoginRequiredMixinfrom the- A Mixin is a class used to add functionality to a class.
LoginRequiredMixinadds the ability to check if a view is logged in, meaning that only logged in users can access it.2.
from django.views.generic import DetailView
- Django's
views.genericIn the moduleDetailViewfrom theDetailViewis a generic view that is useful for creating web pages that show details about a specific object.3.
from .models import PrivateDocument
- The current application's
modelsIn the modulePrivateDocumentImport the model.PrivateDocumentA model is a class that defines the personal document information to be stored in the database.4.
class PrivateDocumentView(LoginRequiredMixin, DetailView):
PrivateDocumentViewDefine a class named- This class implements the
LoginRequiredMixinandDetailViewinherits from- With multiple inheritance
PrivateDocumentViewwill have both the login required feature and the ability to view the detail page.- The order of inheritance is important.
LoginRequiredMixinmust come firstDetailViewwill be executed after login confirmation.5.
model = PrivateDocument
modelattribute is aDetailViewspecifies the model to use.- Here, we'll use the
PrivateDocumentNow that you've specified a model,PrivateDocumentViewThePrivateDocumentCreate a page that shows the details of a specific personal document stored in the model.6.
template_name = 'private_document.html'
template_nameproperty specifies the name of the template file.- Here, we'll use the
private_document.htmlUse the file as a template to organize your personal article detail page.- This template file is called
PrivateDocumentIt is responsible for displaying the object information in the model in HTML format.
Django Views in depth - Creating custom middleware
Middleware is a function or class that performs a specific function in the process of handling web requests and responses. In Django, middleware runs before the request reaches the view and before the response is sent to the client.
The role of middleware
- Processing requests: You can modify the request object, or block requests that don't meet certain conditions.
- Response processing: You can modify the response object, or add any headers you need.
- Handling global features: Implement web application-wide features such as logging, security, caching, and more.
Middleware allows you to put additional logic into the request/response cycle. Let's create a simple logging middleware. The middleware below logs all requests and responses.
class SimpleLoggingMiddleware:
Def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print(f"Request received: {request.path}")
response = self.get_response(request)
print(f"Response sent: {response.status_code}")
return responseCode commentary
1.
class SimpleLoggingMiddleware:
SimpleLoggingMiddlewareDefine a class named middleware. This class will act as the middleware.2.
def __init__(self, get_response):
__init__method is the constructor that is called when the class is instantiated.get_responseis a callable object that points to the next middleware or view function. It is responsible for forwarding requests to the next step in the Django middleware chain.self.get_response = get_responseis the passed inget_responsefunction as a property of the class. This way, the__call__method can call the next level of middleware or view.3.
def __call__(self, request):
__call__methods are the methods that run when the middleware is called; they perform the core middleware logic.requestis an HTTP request object. It contains various pieces of information about the request.4.
print(f"Request received: {request.path}")
- When a request comes in, the request path (
request.path) to the console. We've used f-string to simplify string formatting.5.
response = self.get_response(request)
self.get_response(request)calls the next middleware or view function and returns the result to theresponsevariable. This is the important part of passing the request to the next step.6.
print(f"Response sent: {response.status_code}")
- Before the response is sent to the client, the response status code (
response.status_code) to the console.7.
return response
responseobject. This object can be a response object generated by the next middleware or view, or it can be a response object modified by a later middleware. This is the response that will ultimately be delivered to the client.Bottom line:
SimpleLoggingMiddlewareis a simple middleware that outputs logs when a request comes in and when a response is sent.__call__method outputs the request path, calls the next level of middleware or view, and outputs the response status code. This middleware is calledMIDDLEWAREEnroll in Settings to enable logging of all requests and responses.
Django Views Deeper - Utilizing the View Decorator
A decorator is a feature in Python that you use to wrap a function or class to add or change functionality. View decorators make it easy to apply additional functionality to view functions.
Advantages of View Decorators
- Code reusability: Decorators allow common functionality to be reused across multiple views, reducing code duplication and improving maintainability.
- Code readability: Decorators make your code more readable by separating the core logic of the view from the add-ons.
- Flexibility: Decorators can be combined to easily create views with different functionality.
Decorators make it easy to add extra functionality to your views. For example, let's create a decorator that applies caching.
from django.views.decorators.cache import cache_page
@cache_page(60 * 15) # Cache for 15 minutes
def my_view(request):
# view logic
return HttpResponse("This response is cached for 15 minutes")Code commentary
1.
from django.views.decorators.cache import cache_page
- Django's
views.decorators.cacheIn the modulecache_pageGet the decorator.cache_pageDecorators provide the ability to cache the results of a view for a specified amount of time.2.
@cache_page(60 * 15) # Cache for 15 minutes
@cache_page(60 * 15)Themy_viewfunction to thecache_pageApply the decorator.60 * 15is a value that represents 15 minutes in seconds, meaning that the view's results will be cached for 15 minutes.# Cache for 15 minutesis a comment, which explains the meaning of the code.3.
def my_view(request):
my_viewDefine a view function named- This function returns an HTTP request object (
request) as an argument.4.
# View Logic
- Annotation, indicating where the core logic of the view will go.
- The actual view performs tasks like processing requests, looking up databases, rendering templates, and more.
5.
return HttpResponse("This response is cached for 15 minutes")
HttpResponseobject and pass it the string "This response is cached for 15 minutes" as an argument.- This string is put in the body of the HTTP response and sent to the client.
returnstatement is aHttpResponseobject.Summary
- The above code would be called
my_viewThe view function has acache_pageApply a decorator to cache the results of the view for 15 minutes.- This way, if the same request comes back within 15 minutes, you can improve performance by returning the cached results right away, rather than rerunning the view function.
Django Views Deeper - Using Asynchronous Views
Traditional synchronous views cannot perform other tasks while processing a request. For example, you cannot process other requests while performing a database query, which can create a bottleneck.
Asynchronous views were introduced to address these issues. Asynchronous views allow you to perform other tasks while you wait for an I/O operation to complete. This allows you to process multiple requests simultaneously to increase overall throughput.
Advantages of asynchronous views
- Improved performanceImproves overall throughput by reducing bottlenecks in I/O-bound operations.
- Resource efficiency: Utilize I/O operation latency to efficiently use CPU and memory resources.
- Faster response times: Users can perform other tasks without waiting for the I/O operation to complete, reducing response time.
Django 3.1 supports asynchronous views, which is especially useful for I/O bound operations.
import asyncio
from django.http import HttpResponse
async def async_view(request):
await asyncio.sleep(1) # simulate an asynchronous I/O operation
return HttpResponse("It's an asynchronous view!")Code commentary
1.
import asyncio
- Python's
asyncioImport the module.asynciois a standard library for asynchronous programming.2.
from django.http import HttpResponse
- Django's
httpIn the moduleHttpResponseGet the class.HttpResponseis used when generating HTTP response objects.3.
async def async_view(request):
async_viewDefine an asynchronous view function namedasynckeyword indicates that this function is a coroutine. A coroutine is a function that can run asynchronously.requestis an HTTP request object. It contains various pieces of information about the request.4.
await asyncio.sleep(1) simulate # asynchronous I/O operation
await asyncio.sleep(1)simulates an asynchronous operation that stops for one second.asyncio.sleep(1)returns a Future object that completes in 1 second.awaitkeyword pauses the execution of the coroutine until the Future object is complete.- Annotations
# Asynchronous I/O Operation Simulationexplains the meaning of the code.5.
return HttpResponse("Asynchronous view!")
HttpResponseobject and pass it the string "It's an asynchronous view!" as an argument.- This string is put in the body of the HTTP response and sent to the client.
returnstatement is aHttpResponseobject.Summary
- The above code is an asynchronous view function that simulates an asynchronous operation that stops for one second
async_viewto define theasynckeyword to make the function a coroutine,awaitkeyword to wait for an asynchronous operation.- This view function returns an HTTP response with the string "This is an asynchronous view!".
Performance optimization tips
Django views are the part of your web application that handles the core logic of your web application, and writing efficient views can significantly improve performance.

1. select_relatedand prefetch_related Use
- Issue: When using the ORM to look up related objects, additional database queries are made, which can cause performance degradation.
- Solution:
select_relatedreduces the number of queries by prefetching related objects in a 1:1 or N:1 relationship.prefetch_relatedreduces the number of queries by prefetching related objects in an N:N relationship.
# Get the Book objects related to author in advance
books = Book.objects.select_related('author').all()
# Prefetch Book objects related to publisher (N:N relationship)
books = Book.objects.prefetch_related('publisher').all()2. Utilize DB indexes
- Issue: Searching with unindexed fields reduces performance because the entire database must be searched.
- Solution: Speed up search by adding indexes to frequently queried fields. Django uses the
db_index=Trueoption to create an index.
class Book(models.Model): title = models.CharField(max_length=200, db_index=True) # ...# Get the Book objects related to author in advance
books = Book.objects.select_related('author').all()
# Prefetch Book objects related to publisher (N:N relationship)
books = Book.objects.prefetch_related('publisher').all()3. Caching strategies
- Issue: Looking up infrequently changing data in the database every time is a performance drain.
- Solution: Data that doesn't change often can be stored in a cache to speed up lookups. Django supports a variety of caching backends, and you can apply caching using view decorators or template tags.
class Book(models.Model):
title = models.CharField(max_length=200, db_index=True)
# ...4. Pagination
- Issue: Displaying a lot of data on a single page can increase loading times and hinder the user experience.
- Solution: Use the pagination feature to split data into multiple pages. Django uses
Paginatorclass makes it easy to implement pagination.
5. Query optimization
- Issue: Inefficient queries can overload the database and cause performance degradation.
- Solution: Use the QuerySet API to retrieve only the data you need and reduce unnecessary queries or operations.
# Select only the fields you need
books = Book.objects.only('title', 'author').all()
# Filter only data that meets certain conditions
books = Book.objects.filter(author__name='John Doe').all()Finalize
So far, we've explored Django Views in depth: class-based views, generic views, middleware, and performance optimization techniques. With these features, you'll be able to build more powerful and efficient Django applications.
They may seem complicated at first, but as you apply them one by one and get the hang of them, your Django skills will improve dramatically. Keep experimenting and practicing. We wish you the best on your Django journey!
# Glossary
- Class-Based Views (CBV): How to use classes to implement views
- Generic ViewsViews that pre-implement commonly used view patterns
- Mixins: A class that provides additional functionality to a class
- MiddlewareThe middle layer that handles requests and responses
- DecoratorsHow to modify or extend the functionality of a function or method.
- Asynchronous views: Views that behave asynchronously
- ORM optimization: How to use the Django ORM efficiently
We hope you enjoyed this in-depth look at Django Views and that your Django projects are about to get even more awesome. Good luck!








