[Django advanced] Understand the middleware mechanism and execution sequence in django, and django Middleware

Source: Internet
Author: User
Tags time zones

[Django advanced] Understand the middleware mechanism and execution sequence in django, and django Middleware

The original Article is from Understanding Django Middlewares. This article introduces the definition and function of middleware in django and how to write the middleware-orangleliu by yourself.

Note: The meaning of middleware and middleware is the same in the following article, but they are not completely translated.

Suppose you have read middleware in the Django official document. The following describes the Knowledge mentioned in the document as much as possible, but I hope you will be familiar with it.middlewareBasic concepts.

In this article, we will discuss the following content:

  • What is middleware?
  • When to use middleware
  • What we need to remember when writing middleware
  • Write some middlewares to understand the working process and key points of the middleware.
What is middleware?

Middlewares is used to modify DjangoRequestOrResponseObject hook. Below is a description in the Django document.

Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.
When to use middleware

If you want to modify the request, for exampleHttpRequestObject. Or you want to modifyHttpResponseObjects, which can be implemented through middleware.

You may want to perform some operations before the view execution. In this case, you can use middleware to implement the operation.

Django provides some default middleware, such:
AuthenticationMiddleware

Users may frequently use the view.request.userRight. Django wants to set the user as the request Attribute before each view is executed, so a middleware is used to achieve this goal. Therefore, Django provides middleware that can modify the request object.AuthenticationMiddleware.

Django modifies the request object as follows:

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

For example, if you have an application, its users are people in different time zones. You want them to display the correct time zone when accessing any page, and want all views to get their own timezone information. In this case, you can use the session to solve the problem, so you can add a middleware as follows:

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 depends on request. user, and request. userAuthenticationMiddleware. Therefore
settings.MIDDLEWARE_CLASSESIn configuration, TimezoneMiddleware must be later than AuthenticationMiddleware.

The following example shows more about the middleware sequence.

What should be remembered when Using middleware
  • The order of middlewares is very important.
  • A middleware only needs to inherit the object class
  • One middleware can implement some methods without implementing all the methods.
  • One middleware can implementProcess_request (method)But cannot be implementedProcess_response (method)And process_view. These are common. Django provides many middlewares.
  • One middleware can implementProcess_responseMethod, but does not need to be implementedProcess_requestMethod

AuthenticationMiddleware only processes the request and does not process the response.

GZipMiddleware only processes the response and does not process the request and view. For more information, see the document.

Write some middlewares

First, make sure that you have a Django project that requires a url and a view, and you can enter this view. Next we will perform a few tests on request. user, confirm that the permission is set, and correctly print the request. user information in the view.

Create the middleware. py file in any app.

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

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

Add this middleware to 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',)

Send a request to any url. The following information is printed on the runserver console.

Middleware executed

ModifyBookMiddleware.process_requestAs follows:

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

Accessing a url again will cause an error.

'WSGIRequest' object has no attribute 'user'

This is because the user attribute has not been set for the request object.

Now let's change the order of middlewares,BookMiddlewarePut inAuthenticationMiddlewareLater.

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',)

Access a url. The following figure is printed on the runserver console:

Middleware executed<username>

This indicates that the order in which middlewares processes requests is the same as that listed in settings. MIDDLEWARE_CLASSES.

You can further confirm that middleware. py adds another middleware

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

Add itMIDDLEWARE_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',)

The output is as follows:

Middleware executed<username>Another middleware executed

In the process_request method, return HttpResponse and change BookMiddleware to the following:

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

Try any url and get the following output:

Middleware executed<username>

You will notice the following two things:

  • No matter which url you access, the view processing method you write is not executed, and there is only a response like "some response.
  • AnotherMiddleware. process_request is not executed

Therefore, if the HttpResponse object is returned in the process_request method of Middleware, the later Middleware will be skipped and the processing method in the view will also be skipped.
Therefore, this is rarely done in actual projects (but some projects, such as proxies)

Comment out"return HttpResponse("some response")", And both middleware can process requests normally.

Use process_response

Add the process_response Method to the two middleware instances.

class AnotherMiddleware(object):    def process_request(self, request):        print "Another middleware executed"    def process_response(self, request, response):        print "AnotherMiddleware process_response executed"        return responseclass BookMiddleware(object):    def process_request(self, request):        print "Middleware executed"        print request.user        return HttpResponse("some response")        #self._start = time.time()    def process_response(self, request, response):        print "BookMiddleware process_response executed"        return response

Access some URLs to get the following output:

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

AnotherMiddleware.process_response()InBookMiddleware.process_response()Previously executedAnotherMiddleware.process_request()InBookMiddleware.process_request()Then execute.process_response()The execution sequence is the opposite of process_request.process_response()The execution sequence is from the last middleware to the last, until the first middleware.

Process_view

Django executes middleware in orderprocess_view()From top to bottom. Similar to the order in which process_request () is executed.

So if anyprocess_view()If the HttpResponse object is returnedprocess_view()Will be omitted and will not be executed.

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.