[Django advanced] Understanding the middleware mechanism and execution order in Django

Source: Internet
Author: User
Tags time zones

The original is from understanding Django Middlewares, which describes the middleware definition, function, and how to write middleware –orangleliu in general.

Note: Middleware and middleware have the same meaning in the following article, not completely translated

Let's say you've read the middleware section of the Django official documentation. The knowledge mentioned in the documentation is described in as much detail as possible, but I hope you are familiar with the middleware basic concepts.

In this article we will discuss the following:

    • What is middleware
    • When to use middleware
    • We write what middleware must remember.
    • Write some middlewares to understand the work process and essentials of middleware
What is middleware

Middlewares is a hook that modifies a Django request or response object. The following is a description of the Django document.

aofintoasystemforor output.
When to use middleware

If you want to modify the request, such as the HttpRequest object that is transferred to the view. Or you want to modify the HttpResponse object returned by the view, which can be implemented through middleware.

You might also want to do something before the view executes, which can be done with middleware.

Django provides some default middleware, such as:
AuthenticationMiddleware

You may use it frequently in view request.user . Django wants to set the user to the request property before each view executes, so it uses a middleware to achieve this goal. So Django provides the middleware that can modify the request object AuthenticationMiddleware .

Django modifies the request object in this way:

https://github.com/django/django/blob/master/django/contrib/auth/middleware.py#L22

For example, you have an app whose users are people in different time zones. You want them to be able to display the correct time zone when they visit any page, so that all views can get the user's own timezone information. In this case you can use the session to solve, so you can add a middleware like this:

class TimezoneMiddleware(object):    def process_request(self, request):        # Assuming user has a OneToOneField to a model called Profile        # And Profile stores the timezone of the User.        request.session[‘timezone‘] = request.user.profile.timezone

Timezonemiddleware is dependent on Request.user, Request.user is set by AuthenticationMiddleware . So in
settings.MIDDLEWARE_CLASSESConfiguration, Timezonemiddleware must be after authenticationmiddleware.

The following example gives you more experience with the middleware order.

What to remember when using middleware
    • The order of middlewares is very important.
    • A middleware only needs to inherit the object class
    • A middleware can implement some methods and do not need to implement all the methods
    • A middleware can implement Process_request (methods) but cannot implement Process_response (methods) and Process_view methods. These are common and Django offers a lot of middlewares can do.
    • A middleware can implement the Process_response method, but there is no need to implement the Process_request method

The Authenticationmiddleware only implements the processing of the request and does not handle the response. Reference Document

Gzipmiddleware only implements the processing of the response, and does not implement the request and view processing see the documentation

Write some Middlewares

First make sure you have a Django project that requires a URL and a view, and can enter this view. Below we will do a few tests on request.user, confirm that the permissions are set up, and can print the Request.user information correctly in view.

Create a middleware.py file in any app.

I have an app called books, so the location of the file isbooks/middleware.py

class BookMiddleware(object):    def process_request(self, request):        print"Middleware executed"

Add this middleware in middleware_classes

MIDDLEWARE_CLASSES = (    ‘books.middleware.BookMiddleware‘,    ‘django.contrib.sessions.middleware.SessionMiddleware‘,    ‘django.middleware.common.CommonMiddleware‘,    ‘django.middleware.csrf.CsrfViewMiddleware‘,    ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,    ‘django.contrib.messages.middleware.MessageMiddleware‘,    ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,)

To send a request to any URL, the following information will be printed on the Runserver console.

Middleware executed

Modify the BookMiddleware.process_request following

class BookMiddleware(object):    def process_request(self, request):        print"Middleware executed"        print request.user

Accessing a URL again will cause an error.

‘WSGIRequest‘object‘user‘

This is because the request object has not set the user property yet.

Now let's change the order of the middlewares and BookMiddleware put it AuthenticationMiddleware behind.

MIDDLEWARE_CLASSES = (    ‘django.contrib.sessions.middleware.SessionMiddleware‘,    ‘django.middleware.common.CommonMiddleware‘,    ‘django.middleware.csrf.CsrfViewMiddleware‘,    ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,    ‘books.middleware.BookMiddleware‘,    ‘django.contrib.messages.middleware.MessageMiddleware‘,    ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,)

To access a url,runserver console, print the following

Middleware executed<username>

This shows that middlewares processes the request in the order followed by settings. The order listed in the middleware_classes is consistent.

You can further confirm that middleware.py adds another middleware

class AnotherMiddleware(object):    def process_request(self, request):        print"Another middleware executed"

and add it to theMIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = (    ‘django.contrib.sessions.middleware.SessionMiddleware‘,    ‘django.middleware.common.CommonMiddleware‘,    ‘django.middleware.csrf.CsrfViewMiddleware‘,    ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,    ‘books.middleware.BookMiddleware‘,    ‘books.middleware.AnotherMiddleware‘,    ‘django.contrib.messages.middleware.MessageMiddleware‘,    ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,)

Now the output is:

Middleware executed<username>Another middleware executed

Return HttpResponse in the Process_request method and change the Bookmiddleware to the following:

class BookMiddleware(object):    def process_request(self, request):        print"Middleware executed"        print request.user        return HttpResponse("some response")

Try any of the following URLs and you will get the following output:

Middleware executed<username>

You will notice the following 2 things:

    • No matter which URL you visit, your own view processing method is not executed, only "some response" such a response.
    • Anothermiddleware.process_request not being executed

So if the HttpResponse object is returned in the Process_request method of middleware, then the middleware behind it will be skipped, and the processing method in view is skipped.
So it's rarely done in actual projects (but there are some projects, such as acting as agents).

Comment out "return HttpResponse("some response")" , two middleware can handle the request normally.

Using Process_response

Add a Process_response method to these two middleware

 class anothermiddleware(object):     def process_request(self, request):        Print "Another middleware executed"     def process_response(self, request, response):        Print "Anothermiddleware process_response executed"        returnResponse class bookmiddleware(object):     def process_request(self, request):        Print "Middleware executed"        PrintRequest.userreturnHttpResponse ("Some response")#self. _start = Time.time ()     def process_response(self, request, response):        Print "Bookmiddleware process_response executed"        returnResponse

Access some URLs to get the following output

Middleware executed<username>Another middleware executedAnotherMiddleware process_response executedBookMiddleware process_response executed

AnotherMiddleware.process_response()Executed BookMiddleware.process_response() prior to execution AnotherMiddleware.process_request() BookMiddleware.process_request() . So process_response() the order of execution is exactly the opposite of Process_request. process_response() The order of execution is executed from the last middleware, to the penultimate, and then to the first middleware.

Process_view

The way Django executes the middleware sequentially process_view() , from top to bottom. Similar to the order in which the Process_request () method executes.

So if any one process_view() returns the HttpResponse object, it will be omitted after it process_view() , and will not be executed.

[Django advanced] Understanding the middleware mechanism and execution order in Django

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.