Django运行方式及处理流程总结

学了django有一段时间了,也没深入了解过它内部的实现,正好看到一篇介绍django运行原理的,有图有代码,深度好文,值得收藏。

-- xxmcf 2015.09.28 22:29

原文链接:

之前在网上看过一些介绍Django处理请求的流程和Django源码结构的文章,觉得了解一下这些内容对开发Django项目还是很有帮助的。所以,我按照自己的逻辑总结了一下Django项目的运行方式和对Request的基本处理流程。

一、Django的运行方式

运行Django项目的方法很多,这里主要介绍一下常用的方法。一种是在开发和调试中经常用到runserver方法,使用Django自己的web
server;另外一种就是使用fastcgi,uWSGIt等协议运行Django项目,这里以uWSGIt为例。

1、runserver方法

runserver方法是调试Django时经常用到的运行方式,它使用Django自带的WSGI
Server运行,主要在测试和开发中使用,使用方法如下:

[python] view plain copy

  1. Usage: manage.py runserver [options] [optional port number, or ipaddr:port]
  2. # python manager.py runserver    # default port is 8000
  3. # python manager.py runserver 8080
  4. # python manager.py runserver 127.0.0.1:9090

看一下manager.py的源码,你会发现上面的命令其实是通过Django的execute_from_command_line方法执行了内部实现的runserver命令,那么现在看一下runserver具体做了什么。。

1). 解析参数,并通过django.core.servers.basehttp.get_internal_wsgi_application方法获取wsgi handler;

2). 根据ip_address和port生成一个WSGIServer对象,接受用户请求

[python] view plain copy

  1. def get_internal_wsgi_application():
  2. """
  3. Loads and returns the WSGI application as configured by the user in
  4. ``settings.WSGI_APPLICATION``. With the default ``startproject`` layout,
  5. this will be the ``application`` object in ``projectname/wsgi.py``.
  6. This function, and the ``WSGI_APPLICATION`` setting itself, are only useful
  7. for Django‘s internal servers (runserver, runfcgi); external WSGI servers
  8. should just be configured to point to the correct application object
  9. directly.
  10. If settings.WSGI_APPLICATION is not set (is ``None``), we just return
  11. whatever ``django.core.wsgi.get_wsgi_application`` returns.
  12. """
  13. from django.conf import settings
  14. app_path = getattr(settings, ‘WSGI_APPLICATION‘)
  15. if app_path is None:
  16. return get_wsgi_application()
  17. return import_by_path(
  18. app_path,
  19. error_prefix="WSGI application ‘%s‘ could not be loaded; " % app_path
  20. )

通过上面的代码我们可以知道,Django会先根据settings中的WSGI_APPLICATION来获取handler;在创建project的时候,Django会默认创建一个wsgi.py文件,而settings中的WSGI_APPLICATION配置也会默认指向这个文件。看一下这个wsgi.py文件,其实它也和上面的逻辑一样,最终调用get_wsgi_application实现。

2、uWSGI方法

uWSGI+Nginx的方法是现在最常见的在生产环境中运行Django的方法,本人的博客也是使用这种方法运行,要了解这种方法,首先要了解一下WSGI和uWSGI协议。

WSGI,全称Web
Server Gateway Interface,或者Python Web Server
Gateway
Interface,是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口,基于现存的CGI标准而设计的。WSGI其实就是一个网关(Gateway),其作用就是在协议之间进行转换。(PS:
这里只对WSGI做简单介绍,想要了解更多的内容可自行搜索)

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的Web服务器。uWSGI具有超快的性能、低内存占用和多app管理等优点。以我的博客为例,uWSGI的xml配置如下:

uwsgi>

  • <!-- 端口 -->
  • <socket>:7600</socket>
  • <stats>:40000</stats>
  • <!-- 系统环境变量 -->
  • <env>DJANGO_SETTINGS_MODULE=geek_blog.settings</env>
  • <!-- 指定的python WSGI模块 -->
  • <module>django.core.handlers.wsgi:WSGIHandler()</module>
  • <processes>6</processes>
  • <master />
  • <master-as-root />
  • <!-- 超时设置 -->
  • <harakiri>60</harakiri>
  • <harakiri-verbose/>
  • <daemonize>/var/app/log/blog/uwsgi.log</daemonize>
  • <!-- socket的监听队列大小 -->
  • <listen>32768</listen>
  • <!-- 内部超时时间 -->
  • <socket-timeout>60</socket-timeout>
  • </uwsgi>
  • uwsgi --pidfile=/var/run/geek-blog.pid -x uwsgi.xml --uid blog --gid nogroup

uWSGI和Nginx一起使用的配置方法就不在这里说明了,网上教程很多,需要的可以自行搜索。

二、HTTP请求处理流程

Django和其他Web框架一样,HTTP的处理流程基本类似:接受request,返回response内容。Django的具体处理流程大致如下图所示:

1、加载project settings

创建WSGIServer之前会执行下面的引用:

[python] view plain copy

  1. from django.conf import settings

上面引用在执行时,会读取os.environ中的DJANGO_SETTINGS_MODULE配置,加载项目配置文件,生成settings对象。所以,在manager.py文件中你可以看到,在获取WSGIServer之前,会先将project的settings路径加到os路径中。

2、创建WSGIServer

[python] view plain copy

  1. def run(addr, port, wsgi_handler, ipv6=False, threading=False):
  2. server_address = (addr, port)
  3. if threading:
  4. httpd_cls = type(str(‘WSGIServer‘), (socketserver.ThreadingMixIn, WSGIServer), {})
  5. else:
  6. httpd_cls = WSGIServer
  7. httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
  8. # Sets the callable application as the WSGI application that will receive requests
  9. httpd.set_app(wsgi_handler)
  10. httpd.serve_forever()

其中,WSGIServer继承自wsgiref.simple_server.WSGIServer,而WSGIRequestHandler继承自wsgiref.simple_server.WSGIRequestHandler,wsgiref是Python标准库给出的WSGI的参考实现。其源码可自行到wsgiref参看,这里不再细说。

3、处理Request

第二步中说到的application,在Django中一般是django.core.handlers.wsgi.WSGIHandler对象,WSGIHandler继承自django.core.handlers.base.BaseHandler,这个是Django处理request的核心逻辑,它会创建一个WSGIRequest实例,而WSGIRequest是从http.HttpRequest继承而来

4、返回Response

上面提到的BaseHandler中有个get_response方法,该方法会先加载Django项目的ROOT_URLCONF,然后根据url规则找到对应的view方法(类),view逻辑会根据request实例生成并返回具体的response。

在Django返回结果之后,第二步中提到wsgiref.handlers.BaseHandler.run方法会调用finish_response结束请求,并将内容返回给用户。

三、Django处理Request的详细流程

Django流程图1

Django流程图2

1. 用户通过浏览器请求一个页面

2. 请求到达Request Middlewares,中间件对request做一些预处理或者直接response请求

3. URLConf通过urls.py文件和请求的URL找到相应的View

4. View Middlewares被访问,它同样可以对request做一些处理或者直接返回response

5. 调用View中的函数

6. View中的方法可以选择性的通过Models访问底层的数据

7. 所有的Model-to-DB的交互都是通过manager完成的

8. 如果需要,Views可以使用一个特殊的Context

9. Context被传给Template用来生成页面

a. Template使用Filters和Tags去渲染输出

b. 输出被返回到View

c. HTTPResponse被发送到Response Middlewares

d. 任何Response Middlewares都可以丰富response或者返回一个完全不同的response

e. Response返回到浏览器,呈现给用户

1、Middleware(中间件)

Middleware是在Django BaseHandler的load_middleware方法执行时加载的,加载之后会建立四个列表作为处理器的实例变量:

_request_middleware:process_request方法的列表

_view_middleware:process_view方法的列表

_response_middleware:process_response方法的列表

_exception_middleware:process_exception方法的列表

[python] view plain copy

  1. MIDDLEWARE_CLASSES = (
  2. ‘django.middleware.cache.UpdateCacheMiddleware‘,
  3. ‘django.middleware.common.CommonMiddleware‘,
  4. ‘django.middleware.cache.FetchFromCacheMiddleware‘,
  5. ‘django.contrib.sessions.middleware.SessionMiddleware‘,
  6. ‘django.middleware.csrf.CsrfViewMiddleware‘,
  7. ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,
  8. ‘django.contrib.messages.middleware.MessageMiddleware‘,
  9. ‘django.middleware.locale.LocaleMiddleware‘,
  10. ‘geek_blog.middlewares.MobileDetectionMiddleware‘,    # 自定义的Middleware
  11. )

Django项目的安装并不强制要求任何中间件,如果你愿意,MIDDLEWARE_CLASSES可以为空。中间件出现的顺序非常重要:在request和view的处理阶段,Django按照MIDDLEWARE_CLASSES中出现的顺序来应用中间件,而在response和exception异常处理阶段,Django则按逆序来调用它们。也就是说,Django将MIDDLEWARE_CLASSES视为view函数外层的顺序包装子:在request阶段按顺序从上到下穿过,而在response则反过来。以下两张图可以更好地帮助你理解:

Django Middleware流程1

Django Middleware流程图2

2、URLConf(URL映射)

第一个匹配的view。

DjangoBook了解。

3、Template(模板)

uWSGI
Web服务器介绍

wsgiref源码分析

用Python写一个简单的Web框架

Django
结构及处理流程分析

PS: 以上代码和内容都是基于Django 1.6.5版本,其他版本可能与其不同,请参考阅读。

Over!

原文地址:https://www.cnblogs.com/jiangqiuju/p/8125667.html

时间: 2024-10-12 12:06:17

Django运行方式及处理流程总结的相关文章

Django模板的使用流程-muahao02目录下测试

在我的云主机上,muahao02的测试: Django模板的使用流程 环境:阿里云主机 步骤: 首先建立blog 这个应用 在blog这个目录下手动建立 templates目录,默认的模板就在这个目录下 vim url.py这个文件 vim views.py这个文件 在一级目录下,执行python manage.py runserver 121.42.138.224:8000 [[email protected] templates]# pwd /root/muahao02/blog/templ

Django问卷调查项目思路流程:

Django问卷调查项目思路流程: 1 后端思路 : 需求分析 ---- 找出各实体对应关系 ---- 设计model架构 ---- 统一资源封装 --- 提供资源API入口 ---- 设计项目实体功能 --- 通过API实现实体功能 --- 统一数据结构测试功能 2 项目流程 3 找出各实体之间的对应关系 项目之间实体主要有: 4 根据实体关系与实体功能设计模型 ? 数据模型中包含实现实体功能的各种资源类,都是继承models.Model类,每个模型类的资源,关系键值决定了数据表的整体结构,因

【Django】request 处理流程(转)

Django 和其他 Web 框架的 HTTP 处理的流程大致相同,Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的.我们可以在 Middleware 这个地方把所有 Request 拦截住,用我们自己的方式完成处理以后直接返回 Response. 1. 加载配置 Django 的配置都在 “Project/settings.py” 中定义,可以是 Django 的配置,也可以是自定义的配置,并且都通过 django.conf.settings

Django (九) 项目开发流程&amp;项目架构

项目开发流程&项目架构 1. 软件开发的一般流程 1. 需求分析及确认: 由需求分析工程师与客户确认甚至挖掘需求.输出需求说明文档. ? 2. 概要设计及详细设计: 开发对需求进行概要设计,包括系统的基本处理流程,组织结构.模块划分.接口设计.数据库结构设计等.然后在概要设计的基础上进行详细设计.详细设计中描述实现具体模块所涉及到的主要算法.数据结构.类的层次结构及调用关系,需要说明软件系统各个层次中的每一个程序(每个模块或子程序)的设计考虑,以便进行编码和测试.基本达到伪代码的层面. (原型图

django使用MySQL数据库流程

1.数据迁移 不同的app连接不同的数据库(例子中blog用默认的数据库,blog4用MySQL数据库) (1)要连接MySQL数据库,首先下载MySQL数据库和MySQLdb模块 下载MySQL数据库的参考连接: http://www.cnblogs.com/onlycxue/p/3291889.html 而MySQLdb模块安装参考连接:https://pypi.python.org/pypi/MySQL- python/1.2.4 (我是下载的.exe) (2)接下来就是新建django的

Django学习-3-请求流程

Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串 -> URL对应关系(匹配) -> 视图函数 -> 打开一个HTML文件,读取内容 1.浏览器客户端请求首先到达项目名文件夹下的urls.py urlpatterns = [ url(r'^app1/', include("app1.urls")), url(r'^app2/', include("app2.urls")), ] 2.经过

Django Rest framework序列化流程

目录 一 什么是序列化 二 Django REST framework配置流程之Serializer 三 Django REST framework配置流程之ModelSerializer 一 什么是序列化 序列化模型与序列化关系模型 序列化模型,顾名思义,即对 models 里的数据模型作序列化. 而序列化关系模型则是对 models 里数据模型中带有关系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化. Django Rest Fra

django rest_fremework源码流程总体剖析

1. 序言 有如下django代码,视图层: 1 from django.http import HttpResponse 2 from rest_framework.views import APIView 3 class OrdersView(APIView): 4 def get(self , request , *args , **kwargs): 5 return HttpResponse('GET请求') 6 def post(self , request , *args , **k

django最小程序开发流程

1.建立工程 在工程目录下打开cmd,输入以下命令.其中mysite是项目名称. django-admin startproject mysite 命令运行完后,在该目录下会出现一个名为mysite的文件夹.下面是工程的目录结构 2.创建一个新的应用(app) cmd进入mysite目录(有manage.py那个文件夹),运行以下命令.其中helloapp是应用名 python manage.py startapp helloapp 然后会在manage.py同级目录下生成一个helloapp的