Before looking at some articles on the web that describe the process of Django processing requests and the Django source structure, it's helpful to find out more about the Django project. So I summed up my own logic to see how the Django Project works and the basic processing process for the request.
One, Django operation mode
There are many ways to run Django projects, and here are a few of the most common methods. One is to use the Runserver method frequently in development and debugging, using Django's own Web server, and the other is to run the Django project using protocols such as Fastcgi,uwsgit, taking Uwsgit as an example.
1, Runserver method
The Runserver method is a common way to debug your Django, using the Django Wsgi server, which is used primarily for testing and development, using the following methods:
Usage:manage.py runserver [options] [optional port number, or Ipaddr:port]
# python manager.py runserver # Defaul T Port is 8000
# python manager.py runserver 8080
# python manager.py runserver
Look at manager.py's source code, you will find that the above command is actually through the Django Execute_from_command_line method of implementation of the internal implementation of the Runserver command, now look at what Runserver specifically do.
After looking at the source, you can find that the Runserver command mainly do two things:
1). The analytic parameter, and obtains the WSGI handler by the Django.core.servers.basehttp.get_internal_wsgi_application method;
2. Generate a Wsgiserver object based on IP_Address and port, accept user Request
The source code for the
Get_internal_wsgi_application is as follows: Def get_internal_wsgi_application (): "" "Loads and Returns the WSGI application as configured by the "User in" settings. Wsgi_application '.
With the default ' Startproject ' layout, this is the ' application ' ' object in ' projectname/wsgi.py '. This function, and the ' wsgi_application ' setting itself, are only useful for Django ' s internal servers (runserver, RU NFCGI);
The external WSGI servers should just to the "to" to "configured" correct object application. If settings.
Wsgi_application is isn't set (is "None"), we just return whatever ' django.core.wsgi.get_wsgi_application ' returns. "" "From django.conf import settings App_path = getattr (settings, ' wsgi_application ') if App_path is None:re Turn get_wsgi_application () return Import_by_path (App_path, error_prefix= "Wsgi application '%s ' could Loaded '% App_path '
From the code above we can see that Django will first get the handler based on the wsgi_application in the settings; When you create project, Django creates a wsgi.py file by default, and the Wsgi_application configuration in the settings also points to the file by default. Look at this wsgi.py file, in fact it is the same as the logic above, the final call Get_wsgi_application implementation.
2, Uwsgi method
Uwsgi+nginx's approach is now the most common way to run Django in a production environment, my blog is also the use of this method to run, to understand this approach, first of all to understand the WSGI and UWSGI protocol.
WSGI, full name Web server gateway Interface, or Python Web server gateway Interface, is a simple and generic interface between Web servers and Web applications or frameworks defined for the Python language , and is designed based on existing CGI standards. WSGI is actually a gateway, the function of which is to convert between protocols. (PS: This is only a brief introduction to Wsgi, want to know more content to search by themselves)
UWSGI is a Web server that implements protocols such as WSGI Protocol, UWSGI, HTTP, and so on. Note that UWSGI is a communication protocol, and UWSGI is a Web server that implements the UWSGI protocol and the WSGI protocol. UWSGI has the advantages of super fast performance, low memory footprint and multiple app management. Take my blog For example, Uwsgi's XML configuration is as follows:
<uwsgi>
<!--port-->
<socket>:7600</socket>
<stats>:40000</stats>
<!--system environment variable-->
<env>DJANGO_SETTINGS_MODULE=geek_blog.settings</env>
<!-- The specified Python wsgi module-->
<module>django.core.handlers.wsgi:wsgihandler () </module>
< processes>6</processes>
<master/>
<master-as-root/>
<!--timeout settings-->
The above is the UWSGI XML configuration, but also the way to use the INI. The commands for installing UWSGI and running are as follows:
sudo pip install uwsgi
uwsgi--pidfile=/var/run/geek-blog.pid-x uwsgi.xml--uid Blog--gid nogroup
The configuration method used with Uwsgi and Nginx is not explained here, there are a lot of tutorials on the web, and you need to search for them yourself.
ii. HTTP request processing Process
Like Django and other web frameworks, HTTP processes are basically similar: Accept request and return response content. The details of the Django process are outlined in the following illustration:
1. Load Project Settings
When you create project through django-admin.py, Django automatically generates the default settings files and manager.py files, and the following references are executed before the Wsgiserver is created:
From django.conf Import settings
The above reference, when executed, reads the Django_settings_module configuration in Os.environ, loads the project configuration file, and generates the SETTINGS object. So, as you can see in the manager.py file, you add project's settings path to the OS path before you get the wsgiserver.
2. Create Wsgiserver
Whether you run the Django project using Runserver or UWSGI, the Run () method in Django.core.servers.basehttp is invoked at startup. Creates an instance of the Django.core.servers.basehttp.WSGIServer class, and then calls its Serve_forever () method to start the HTTP service. The source code for the Run method is as follows:
def run (addr, port, Wsgi_handler, Ipv6=false, threading=false):
server_address = (addr, port)
if threading:
httpd_cls = Type (str (' Wsgiserver '), Socketserver. ThreadingMixIn, Wsgiserver), {})
else:
httpd_cls = wsgiserver
httpd = Httpd_cls (server_address, Wsgirequesthandler, Ipv6=ipv6)
# Sets The callable application as the WSGI application that'll receive requests
Httpd.set_app (Wsgi_handler)
httpd.serve_forever ()
As above, we can see that the HTTP request handler is specified when the Wsgiserver instance is created, and the above code uses Wsgirequesthandler. When a user's HTTP request arrives at the server, Wsgiserver creates an Wsgirequesthandler instance and uses its handler method to process the HTTP request ( In fact, it is called the Run method in Wsgiref.handlers.BaseHandler. Wsgiserver the Set_app method to set a callable (callable) object as a application, the handler method mentioned above will eventually invoke the Set application processing request and return to response.
Among them, Wsgiserver inherited from Wsgiref.simple_server. Wsgiserver, and Wsgirequesthandler inherits from Wsgiref.simple_server. Wsgirequesthandler,wsgiref is the WSGI reference implementation given by the Python standard library. Its source code can go to Wsgiref see, here no longer elaborate.
3, processing request
The application in the second step, In Django It's usually the Django.core.handlers.wsgi.WSGIHandler object, Wsgihandler inherits from Django.core.handlers.base.BaseHandler, this is the Django processing request Core logic, it creates a wsgirequest instance, and Wsgirequest is inherited from Http.httprequest.
4. Return to Response
In the Basehandler mentioned above, there is a get_response method that loads the root_urlconf of the Django project and then finds the corresponding view method (class) based on the URL rule. The view logic generates and returns a specific response based on the request instance.
After Django returns the results, the second step mentions that the Wsgiref.handlers.BaseHandler.run method invokes the Finish_response end request and returns the content to the user.
detailed procedures for Django processing request
The third and fourth steps above are just about the process, and Django does a lot of things when it comes to processing the request. First, share two of the Django flowcharts you see online:
Django Flowchart 1
Django Flowchart 2
The above two flowcharts can roughly describe the process of Django processing request, and can be divided into the following steps in accordance with the annotations in Flowchart 2:
1. Users request a page through the browser
2. Requests arrive at request Middlewares, middleware to do some preprocessing or direct response request
3. urlconf find the corresponding view by urls.py the file and the URL of the request
4. View Middlewares is visited, it can also do some processing or directly return to the request response
5. Call the function in view
6. The method in view can selectively access the underlying data through models
7. All model-to-db interactions are done through the manager
8. Views can use a special context if needed
9. Context is passed to template to generate pages
A. Template use filters and tags to render output
B. Output is returned to view
C. HttpResponse was sent to response middlewares
D. Any response middlewares can enrich the response or return to a completely different response
E. Response returned to the browser and presented to the user
The main parts of the above process are: middleware (middleware, including request, view, exception, response), URLConf (URL mapping relationship), Template (template system), described below.
1, middleware (middleware)
Middleware is not something that is unique to Django, and it is also a concept in other web frameworks. In Django, middleware can penetrate four stages of the process: Request,view,response and exception, corresponding to each middleware class Rocess_request,process_ View, Process_response and process_exception these four methods. You can define any one of these multiple methods, depending on which processing phase you want the middleware to function in. Each method can return a response object directly.
Middleware is loaded when the Load_middleware method of the Django Basehandler is executed, and after loading, four lists are created as instance variables of the processor:
- List of _request_middleware:process_request methods
- List of _view_middleware:process_view methods
- List of _response_middleware:process_response methods
- List of _exception_middleware:process_exception methods
The Django middleware is defined in the middleware_classes tuple of its configuration file (settings.py). In Middleware_classes, the middleware component is represented by a string: A complete Python path to the middleware class name. For example, the configuration of the Geekblog project:
middleware_classes = (
' django.middleware.cache.UpdateCacheMiddleware ',
' Django.middleware.common.CommonMiddleware ',
' django.middleware.cache.FetchFromCacheMiddleware ',
' Django.contrib.sessions.middleware.SessionMiddleware ',
' django.middleware.csrf.CsrfViewMiddleware ',
' Django.contrib.auth.middleware.AuthenticationMiddleware ',
' Django.contrib.messages.middleware.MessageMiddleware ',
' django.middleware.locale.LocaleMiddleware ',
' Geek_blog.middlewares.MobileDetectionMiddleware ', # Custom middleware
)
The Django Project installation does not force any middleware, and middleware_classes can be empty if you wish. The order in which the middleware appears is very important: in the process of request and view, Django applies the middleware in the order in which it appears in Middleware_classes, and in the response and exception exception handling phases, Django calls them in reverse order. That is, Django treats middleware_classes as the order wrapper for the outer layer of the view function: it crosses from top to bottom in the request phase and vice versa in response. The following two diagrams can help you better understand:
Django Middleware Process 1
Django Middleware Flowchart 2
2, URLConf (URL mapping)
If the middleware handling request does not return response directly, Django resolves the URL of the user request. Urlconf is the directory of Web sites that Django supports. Its essence is the URL pattern and the mapping table between the view functions to be called for that URL pattern. In this way you can tell Django that the code is invoked for that URL, and the code is invoked for that URL. Specifically, there are root_urlconf constants in the Django project's configuration file, this constant plus the root directory "/", Creates an instance of the Django.core.urlresolvers.RegexURLResolver as a parameter and then resolves the URL of the user request through its Resolve method to find the first matching view.
Other related urlconf content, here no longer specifically introduced, we can see Djangobook understand.
3, Template (template)
Most web frameworks have their own template (template) systems, as are Django. However, the Django template is different from the Mako template and the jinja2 template, and the Django template cannot write Python code directly, only through additional definitions of filter and template tag. Since this article mainly introduces the Django process, the template content is not too much introduced.
PS: The above code and content are based on the Django 1.6.5 version, other versions may be different, please refer to the reading.
over!