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 views In the module View Get the class.
  • View Classes are the basic classes that you inherit when you create a class-based view (CBV).
2. from django.http import HttpResponse
  • Django's http In the module HttpResponse Get the class.
  • HttpResponse class is used when generating HTTP responses.
3. class HelloView(View):
  • HelloViewDefine a class named
  • This class implements the View class inherits from.
  • That is, HelloViewwill be a class-based view.
4. def get(self, request):
  • HelloView Inside the class get.
  • get method 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!")
  • HttpResponse object 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.
  • return statement is a HttpResponse object.

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 View class inherits from.
  • That is, MyViewbecomes a Class-Based View (CBV).
2. def get(self, request):
  • MyView Inside the class get.
  • get method 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")
  • HttpResponse object 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.
  • return statement is a HttpResponse object.
5. def post(self, request):
  • MyView Inside the class postmethod called
  • post method 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")
  • HttpResponse object 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.
  • return statement is a HttpResponse object.

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.generic In the module ListView Get 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 models In the module Book Import the model.
  • Book A 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 ListView class inherits from.
  • That is, BookListViewThe ListViewto create a book listing page.
4. model = Book
  • model attribute is a ListViewspecifies the model to use.
  • Here, we'll use the Book Now that you've specified a model, BookListViewThe Book Create a page showing a list of books stored in the model.
5. template_name = 'book_list.html'
  • template_name property specifies the name of the template file.
  • Here, we'll use the book_list.html Use the file as a template to organize your book listing page.
  • This template file is called Book Serves to display a list of objects in the model in HTML format.
6. context_object_name = 'books'
  • context_object_name property specifies the name of the list of objects to use in the template.
  • By default, the ListViewThe object_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.mixins In the module LoginRequiredMixinfrom 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.generic In the module DetailViewfrom the
  • DetailViewis 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 models In the module PrivateDocument Import the model.
  • PrivateDocument A 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 LoginRequiredMixinand DetailViewinherits 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 first DetailViewwill be executed after login confirmation.
5. model = PrivateDocument
  • model attribute is a DetailViewspecifies the model to use.
  • Here, we'll use the PrivateDocument Now that you've specified a model, PrivateDocumentViewThe PrivateDocument Create a page that shows the details of a specific personal document stored in the model.
6. template_name = 'private_document.html'
  • template_name property specifies the name of the template file.
  • Here, we'll use the private_document.html Use the file as a template to organize your personal article detail page.
  • This template file is called PrivateDocument It 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 response

Code 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 in get_response function 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 the response variable. 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
  • response object. 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 called MIDDLEWARE Enroll 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.cache In the module cache_page Get the decorator.
  • cache_page Decorators 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)The my_view function to the cache_page Apply 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")
  • HttpResponse object 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.
  • return statement is a HttpResponse object.
Summary
  • The above code would be called my_view The view function has a cache_page Apply 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 asyncio Import the module. asynciois a standard library for asynchronous programming.
2. from django.http import HttpResponse
  • Django's http In the module HttpResponse Get the class. HttpResponseis used when generating HTTP response objects.
3. async def async_view(request):
  • async_viewDefine an asynchronous view function named
  • async keyword 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.
  • await keyword 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!")
  • HttpResponse object 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.
  • return statement is a HttpResponse object.
Summary
  • The above code is an asynchronous view function that simulates an asynchronous operation that stops for one second async_viewto define the
  • async keyword to make the function a coroutine, await keyword 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.

Django Views 심화 - 성능 최적화 팁 요약 이미지

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=True option to create an index.
Pythonclass 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 Paginator class 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!

테리 이모티콘
(Happy coding!)
테리 이모티콘
(Happy coding!)

Similar Posts