What does django do from request to response

  • 2020-12-05 17:17:55
  • OfStack

preface

Recently, during the interview, I was asked a question by the interviewer, that is, how did request get the user in user? This question was not answered at that time, which can be said to be very embarrassing, so I quickly looked up some materials and looked at some source code, specifically to summarize 1 question.

To answer the question of why the user can get the request directly through request.user, you should first look at the process by which the request is processed and how the response is returned. Today I want to summarize what django did from request to response.

WSGI

When a client sends a request, the first server that handles the request is actually the web server, which is often referred to as nginx, Apache and other web servers, and WSGI's job is to connect the web server to the web framework (Django). WSGI is divided into two parts: server side and application side. To process an WSGI response, the server executes the application and provides a callback function to the application, which processes the request and returns the response to the server using the provided callback.

Essentially, I think of WSGI as a contact between the web server and the django application.

The data flow

When a user sends a request to your application, an WSGI handler will be initialized to do the following:

Import the exception classes for ES43en.py and django The load_middleware method is used to load MIDDLEWARE_CLASSES in ES48en.py or middleware classes used in MIDDLEWARES tuples. Create four lists (_request_middleware,_view_middleware, _response_middleware, _exception_middleware) containing methods to handle request,view,response, and exception, respectively. WSGI Handler will instantiate a django. http. HTTPRequest object's subclasses, django. core. handlers. wsgi. WSGIRequest. Loop through the methods that process request (_request_middleware list) and call them in order Resolve url for the request Loop through each method that processes view (_view_middleware list) If it does, it calls the view function Methods to handle any exceptions (_exception_middleware list) Loop through each method that processes the response (_response_middleware list), (from the inside out, in the reverse order of the requesting middleware) You get a response and call the callback provided by web server

The middleware

Middleware has been used in many key features of django: for example, CSRF intermediate keys are used to prevent cross-site request forgery attacks. They are also used to process session data, and authentication and authorization are also done by middleware. We can also write our own middleware to tune or (short-circuit) the data flow through the application.

django middleware contains at least one of the following four methods: process_request, process_response, process_view, process_exception. These methods are collected by WSGI handler and called sequentially.

process_request

We can let's look at django. contrib. auth. middleware. AuthenticationMiddleware:


def get_user(request):
 if not hasattr(request, '_cached_user'):
  request._cached_user = auth.get_user(request)
 return request._cached_user

class AuthenticationMiddleware(MiddlewareMixin):
 def process_request(self, request):
  assert hasattr(request, 'session'), (
    "The Django authentication middleware requires session middleware "
    "to be installed. Edit your MIDDLEWARE%s setting to insert "
    "'django.contrib.sessions.middleware.SessionMiddleware' before "
    "'django.contrib.auth.middleware.AuthenticationMiddleware'."
  ) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
  request.user = SimpleLazyObject(lambda: get_user(request))

Here we can see that the attribute request.user is generated in AuthenticationMiddleware. We'll talk about that later.

Here we can see that the middleware only has process_request, indicating that it only handles the data flow in and out of the django application in step 1 of request. The middleware first verifies that the session middleware is being used and then sets up the user by calling the get_user function. When WSGI handlers iterate

When the process_request method is listed, it will build the request object that will eventually be passed to the view function and enable you to refer to request.user. Some middleware does not have the process_request method, at this stage, it will be skipped.

process_request should return the None or HTTPResponse object. When None is returned, WSGI handler continues to load the methods in process_request, but the latter case short-circuits the processing and enters the process_response loop.

Parsing url

When all process_request are called, we get an request object that will be passed to the view function. Before this event occurs, django must parse url and decide which view function to call. This process is as simple as using regular matching. There is an ROOT_URLCONF key in ES173en.py to specify root ES177en.py, which will contain all of your app's ES180en.py files. If no match is successful, one exception will be thrown django. core. urlresolvers. Resolver404, this is django http. HTTP404 subclass.

process_view

After this step, WSGI handler knows which view function to call and which parameters to pass. It calls the methods in the middleware list once more, this time _view_middleware list. The process_view method for all Django middleware will be declared as follows:


process_view(request, view_function, view_args, view_kwargs)

Like process_request 1, the process_view function must return an None or HTTPResponse object so that WSGI handler continues to process the view or 'short-circuiter' process and returns a response. There is a method of process_view in CSRF middleware. When CSRF cookies appears, the process_view method will return None and the view function will continue. If not, the request will be rejected, the process will be 'short-circuited', and an error message will be generated.

Enter the view function

A view function needs to meet three conditions:

It has to be callable. This can be a function-based view or a view of ES231en-ES232en (inherited from View and made callable using the as_view() method. These method calls depend on HTTP verb(GET, POST, etc)) An HTTPRequest object must be accepted as the first position parameter. This HTTPRequest object is the result of being processed by all process_request and process_view middleware methods. You must either return an HTTPResponse object or throw an exception. It is this response object that is used to open the process_view loop of WSGI handler.

process_exception

If the view function throws an exception, Handler will loop through the _exception_middleware list, executing the methods in reverse order, from the last middleware item listed in ES261en.py to the first. If an exception is thrown, the process will be short-circuited and the other process_exception will not be executed. Normally we rely on the exception handler provided by Djnago 's BaseHandler, but we can also use custom exception handling middleware.

process_response

At this stage, we get an HTTPResponse object, which may be returned by process_view, or by the view function. We will now loop through the response middleware. This is the middleware's last chance to tweak the data. The order of execution is from the inside out.

Take cache middleware's process_response as an example: It depends on the different states in your app (whether the cache is on or off, whether a data stream is being processed) to cache your response.

Pay attention to

Differences between django 1.10 and previous versions:

In the old version of MIDDLEWARE_CLASSES, all middleware called their process_response methods even if one middleware "short-circuded" the execution. In the new VERSION of MIDDLEWARES, the process_response method is invoked only by this middleware and the middleware executed before it.

conclusion

This is the basic process of django processing one request. Finally, WSGI Handler of django creates a return value from HTTPResponse, and calls a callback function to pass the data to web server before returning it to the user.

Here are two key points:

We now know how the view function matches the url parser and what is calling it (WSGI Handler)

There are four key places you can hook into the request/response cycle: process_request, process_response, process_view, process_exception. The request middleware executes from the outside to the inside, finally arrives at the view function, and then returns from the inside out through the response middleware.

The resources

Django Middlewares and the Request/Response Cycle How Django processes a request

conclusion


Related articles: