Django(35)Django请求生命周期分析(超详细)
Django请求生命周期分析

1.客户端发送请求
- 在浏览器输入url地址,例如
www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都实现了HSTS机制,服务器自动从http协议重定向到https协议 - 在网页中点击超链接或
javascript脚本进行url跳转,仅设置href='绝对路径',浏览器会自动使用当前url的协议、host和port,例如在https://tieba.baidu.com/index.html网页中,点击一个超链接/f?kw=chinajoy,会自动访问https://tieba.baidu.com/f?kw=chinajoy
2. 路由转发
- IP查找:因特网内每个公有IP都是唯一的,域名相当于IP的别名,因为我们无法去记住一大堆无意义的IP地址,但如果用一堆有意义的字母组成,大家就能快速访问对应网站
- DNS解析:通过域名去查找IP,先从本地缓存查找,其中本地的
hosts文件也绑定了对应IP,若在本机中无法查到,那么就会去请求本地区域的域名服务器(通常是对应的网络运营商如电信),这个通过网络设置中的LDNS去查找,如果还是没有找到的话,那么就去根域名服务器查找,这里有所有因特网上可访问的域名和IP对应信息(根域名服务器全球共13台) - 路由转发:通过网卡、路由器、交换机等设备,实现两个IP地址之间的通信。用到的主要就是路由转发技术,根据路由表去转发报文,还有子网掩码、IP广播等等知识点
3.建立连接
通过TCP协议的三次握手建立连接
4.传输报文
建立连接后,客户端会通过TCP依次、有序的发送一定大小的报文,其中包括了超时重传、阻塞窗口等等概念,用来保证数据包的完整、有序
- http协议使用的明文传输,所有内容都是直接可读的
- https协议是基于
SSL/TLS加密,而SSL/TLS是基于TCP协议的,也就是http协议报文包装成TCP报文进行的加密,使用https协议的话,如果本地没有证书和公钥,那么会从服务器获取证书并且进行验证,流程如下:

5.nginx处理
当前django框架开发的web项目,主流使用的服务器架构是:nginx+uWSGI+django
nginx监听公网IP的某个端口,例如80,接收到请求后,分2种情况处理请求:
- 如果是静态资源(如javascript、css、图片等)的请求,那么
nginx直接获取到该资源,返回给用户 - 如果是动态内容的请求,那么
nginx就将请求转发到uWSGI,使用的协议一般都是uwsgi,性能最好
注意:
- 有些
reqeust会分多个数据包进行发送,nginx会缓存等待整个request接收完成才调用uWSGI - 如果使用的
https,那么加密、解密都在nginx中进行处理
6.uWSGI处理
uWSGI监听本机IP的某个端口,例如3308,接收到nginx转发来的请求后,通过将http协议转换为WSGI协议,和django程序之间进行通信
7.WSGIHandler处理
当django接受到一个请求时,会初始化一个WSGIHandler,可以在项目下的wsgi.py文件进行跟踪查看:
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.load_middleware()
def __call__(self, environ, start_response):
set_script_prefix(get_script_name(environ))
signals.request_started.send(sender=self.__class__, environ=environ)
request = self.request_class(environ)
response = self.get_response(request)
......
它接受2个参数:
- environ:是含有服务器端的环境变量
- start_response:可调用对象,返回一个可迭代对象。
这个handler控制了从请求到响应的整个过程,首先的就是加载django的settings配置,然后就是调用django的中间件开始操作
8.middleware中间件处理
django操作中间件,首先会调用process_request方法,该方法的作用是处理请求对象,它的参数是request,返回有2种情况
- response:调用process_response列表处理
- None:调用下一个中间件的process_request处理
返回response之后的中间件及其业务逻辑都不会处理,直接回返回给浏览器
返回None则表示会继续调用下一个中间件,处理下一个中间件中的逻辑
django项目默认有一些自带的中间件,如下:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
]
process_request会从上往下依次调用MIDDLEWARE中的中间件,注意:中间件的执行是有顺序的,所以我们一般自定义中间件的时候,我们都会将自定义的中间件放到列表最下面

9.URLConf路由匹配
通过urls.py文件中的 urlpatterns 配置找到对应的 视图函数或者视图类的方法,如果没有找到匹配的方法,那么就会触发异常,由中间件的process_exception 进行处理
process_exception:在视图函数或中间件处理过程抛出异常时调用
参数:
- request:请求对象
- exception:是处理过程中抛出的异常对象
返回:
- response:之后的
process_exception都不会触发,而是调用process_response处理 - None:调用上一个中间件的
process_exception处理
10.middleware的process_view
我们通过路由调用视图之前,会调用中间件的process_view方法进行预处理
process_view:视图预处理,在视图函数处理之前调用
参数:
- view_func:url路由匹配到的视图函数
- view_args:视图函数的可变参数
- view_kwargs:视图函数的可变关键字参数
返回:
- response:调用
process_response处理 - None:调用下一个中间件的
process_view处理
11.views处理request
调用对应的视图函数或视图类的方法处理request,例如获取GET和POST参数,并且调用特定的模型对象执行数据库操作,如果没有数据库操作,那么就直接跳到我们后续的14步了
12.models处理
视图方法中,一般情况下都需要调用模型类进行数据操作,一般是通过模型的manager管理类进行操作的,如:MyModel.objects.get(pk=1)
如果没有数据操作,那么这一步和下一步就忽略
13.数据库操作
如果django通过模型类执行对数据库的增删改查,那么此时整个流程就会在对应的数据库中执行
14.views处理数据
视图方法获取到数据后:
- 将数据封装到一个
context字典当中,然后调用指定的template.html,通过模板中的变量、标签和过滤器等,再结合传入的数据context,会触发中间件的process_template_response方法,最终渲染成HttpResponse - 不调用模板,直接返回数据,譬如
JsonResponse、FileResponse等 - 执行
redirect,生成一个重定向的HttpResponse,触发中间件的process_response后,返回到客户端,结束该web请求的生命周期
15.middleware的process_response
调用中间件的 process_response 方法进行处理,最后一个中间件的process_response执行完成后,返回到WSGIHandler类中
16.WSGIHandler处理
WSGIHandler类获取到response后
- 先处理
response的响应行和响应头,然后调用start_response返回http协议的 响应行和响应头 到uWSGI,这个start_response只能调用一次 - 第一步处理完成后,如果是文件需要对
response进行,否则就直接将response作为http协议的body部分返回给uWSGI
17.uWSGI处理
uWSGI接收到django程序的返回后,将所有内容包装成http协议的内容后,通过uwsgi协议返回给nginx服务器处理
18.nginx处理
nginx获取到uWSGI的返回后,将response通过TCP协议返回给客户端
19.客户端接收响应
客户端接收到服务器的响应后,做对应的操作,例如:显示在浏览器中,或是javascript的处理等至此,整个web请求的生命周期结束。
Django(35)Django请求生命周期分析(超详细)的更多相关文章
- Django(47)drf请求生命周期分析
前言 一般我们写完序列化以后,我们就会开始写视图了,drf中我们一般使用CBV的方式,也就是类视图的方式,最基础的我们会使用from rest_framework.views import API ...
- Django简介,请求生命周期,静态文件配置
Web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...
- drf框架概况-resful接口规范-请求模块-渲染模块-Postman-drf请求生命周期
drf框架 全称:django-rest- framework 知识点: """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码-基于restful ...
- Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- Django组件 - Django请求生命周期、中间件
一.Django请求生命周期 在学习中间件之前,先了解一下Django的请求生命周期,如下图: 1)client代表浏览器,浏览器内部为我们封装了socket,Django的WSGI模块也封装了soc ...
- Django组件---Django请求生命周期和中间件
Django组件---Django请求生命周期和中间件 Django请求生命周期 说明: client代表浏览器,浏览器的内部为我们封装了socket,Django的WSGI模块也为我们封装了sock ...
- Django中间件-跨站请求伪造-django请求生命周期-Auth模块-seettings实现可插拔配置(设计思想)
Django中间件 一.什么是中间件 django中间件就是类似于django的保安;请求来的时候需要先经过中间件,才能到达django后端(url,views,models,templates), ...
- django请求生命周期,FBV和CBV,ORM拾遗,Git
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
随机推荐
- 自动化kolla-ansible部署ubuntu20.04+openstack-victoria之镜像制作centos6.5-14
自动化kolla-ansible部署ubuntu20.04+openstack-victoria之镜像制作centos6.5-14 欢迎加QQ群:1026880196 进行交流学习 制作OpenSta ...
- React函数式组件的性能优化
优化思路 主要优化的方向有2个: 减少重新 render 的次数.因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 ...
- day-26-封装-property装饰器-反射
一.super进阶 在多继承中:严格按照mro顺序来执行 super是按照mro顺序来寻找当前类的下一类 在py3中不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法 在py2中的 ...
- 关于js中的回调函数callback,通俗易懂
前言 其实我一直很困惑关于js 中的callback,困惑的原因是,学习中这块看的资料少,但是平时又经常见,偶尔复制一下前人代码,功能实现了也就不再去追其原由,这么着,这个callback的概念就越来 ...
- 【布隆过滤器】基于Hutool库实现的布隆过滤器Demo
布隆过滤器出现的背景: 如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定.链表.树.散列表(又叫哈希表,Hash table)等等数据结构都是这种思路,存储 ...
- Thinkphp之PHPExcel类库函数的官方读取的几个例子
1.使用 PHPExcel_IOFactory 读取文件 $objPHPExcel = PHPExcel_IOFactory::load($inputFileName); 2.使用一个特定的读取类,读 ...
- hdu1251 hash或者字典树
题意: 统计难题 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量 ...
- UVA11419 我是SAM
题意: 给你一个n*m的矩阵,上面有一些格子上有目标,我们可以在格子的外面用枪打目标,一发子弹可以消灭一行或者一列目标,问你最少多少枪能把目标打光,并且输出开枪的位置,题目没说spj(特判) ...
- (转)VMware中桥接模式与NAT模式的区别
bridged networking(桥接模式) 在这样的模式下.VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机,它能够訪问网内不论什么一台机器. 在桥接模式下.你须要手工为虚拟系统配置 ...
- C++基础:模板的声明实现分离
模板的声明和实现为什么不能分离我不想废话了,我只是在想一种能够分离的方式. 文件 test.h 1 #pragma once 2 3 template<typename TC> 4 cla ...