Django底层剖析之一次请求到响应的整个流程
As we all know,所有的Web应用,其本质上其实就是一个socket服务端,而用户的浏览器就是一个socket客户端。
#!/usr/bin/env python
#coding:utf-8 import socket def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n")
client.send("Hello, Seven") def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',8000))
sock.listen(5) while True:
connection, address = sock.accept()
handle_request(connection)
connection.close() if __name__ == '__main__':
main()
上述代码使用socket实现了其本质,对于所有的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,避免大家重复的造轮子,因此有人发明了相关的工具——Web框架,for example:Django、Flask、web.py and so on。不同的框架可能采用不同的目录结构,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。以前,如何选择合适的Web应用程序框架成为困扰Python初学者的一个问题,这是因为,一般而言,Web应用框架的选择将限制可用的Web服务器的选择,反之亦然。那时的Python应用程序通常是为CGI,FastCGI,mod_python中的一个而设计,甚至是为特定Web服务器的自定义的API接口而设计的。
PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受, 它已基本达成它的可移植性方面的目标。
概述:
Django的请求到响应的流程,简单的来说就是利用wsgi,当用户发来一个request进行response,响应前发送request_started信号,经过中间件的process_request,响应完成后会调用中间件的process_response。
1.浏览器端用户用url发来了一个请求
当django程序启动时,会根据settings中:
源码截图:
(注:这里是project名.wsgi.application,博主创建的project名为s3。)
执行applicaion对应的函数:
源码截图:
接下来我们来看get_wsgi_application函数:
源码截图:
从上述源码可看出django每次请求响应都会返回一个WSGIHandler类的实例。
WSGIHandler类源码截图:
这里,我们需要关注的是:
load_middleware只有第一次请求会调用,即中间件的加载只会在第一次请求时执行。
WSGIhandler类中发送了request_started信号。
下来我们首先关注一下他的父类base.BaseHandler类:
base.BaseHandler类源码截图:
中间件的完整执行流程图:
备注:由上图可看出:
- 当请求到来时,会首先经过中间件的Process_Request,如果Process_Request有return即当前url没有通过中间件,则程序直接跳转到最后一个Process_Response,然后逆序执行所有的Process_Response。
- 然后程序会进入url,这时程序会检测用户有没有设置process_view,如果有,则接下来先执行process_view,如果process_view有return,则程序直接跳转到最后一个Process_Response,然后逆序执行所有的Process_Response。
- 如果上一步没有process_view,程序会执行views文件中的函数
- 执行完上一步,程序会检测有没有异常出现,如果有,则先执行中间件类对应的process_exception
- 最后,程序会逆序执行所有的Process_Response。
备注:request_middleware、view_middleware 是顺序执行,template_response_middleware、response_middleware、exception_middleware 是逆序执行。
url:
首先程序会根据配置文件中:
源码截图:
(同样这是是project名.urls)
找到urls.py文件
url匹配源码:
这里直接使用当前url是否属于LocaleRegexURLResolver这个类。
LocaleRegexURLResolver类:
预编译:
正则匹配:
我们需要关注的是LocaleRegexURLResolver类的resolve方法:
注:self.url_patterns是所有的正则url,这里对正则url进行循环;new_path是用户输入的url,这里pattern.resolve是执行RegexURLPattern类的resolve方法:
由上述源码可看出RegexURLPattern类的resolve方法即通过regex.search进行具体的匹配操作,其中regex封装了re模块。
我们定义的url:
示例代码:
from django.conf.urls import url
from django.contrib import admin
from APP01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^articles/(?P<year>[0-9]{4})/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
源码url截图:
从上述源码中可看出url方法接收正则表达式和view两个参数,最终返回一个RegexURLPattern对象,RegexURLPattern类对正则表达式和view做进一步处理
由上述源码可看出,在完成正则匹配后,view会被作为回调函数运行。由此解释了url是如何与views函数进行绑定的。
接下来,程序调用views函数,并对模板进行渲染,并返回到view,程序如果没有异常,执行中间件的Process_Response(详见上文中间件的执行流程),最终程序发送一个信号 request_finished信号,订阅这个信号的事件会清空并释放任何使用中的资源。
如果您觉得本文对您有参考价值,欢迎帮博主点击文章下方的推荐,谢谢!
Django底层剖析之一次请求到响应的整个流程的更多相关文章
- Django:学习笔记(4)——请求与响应
Django:学习笔记(4)——请求与响应 0.URL路由基础 Web应用中,用户通过不同URL链接访问我们提供的服务,其中首先经过的是一个URL调度器,它类似于SpringBoot中的前端控制器. ...
- 第一个Django应用 - 第一部分:请求与响应
一. 新建项目 进入你期望的项目保存目录,运行下面的命令: $ django-admin startproject mysite 这将在目录下生成一个mysite目录,也就是你的这个Django项目的 ...
- Django:(03)请求和响应
一.HttpRequest 客户端传参的几种方式 传递方式 示例 后端获取方式 数据类型 url路径(path) /news/1/2 正则匹配 str 查询字符串 /news2?category=1& ...
- python的Web框架,Django框架中的请求与响应
请求与响应 简单流程图 我们先来了解一个请求与响应的大概流程 视图函数接受到的request到底是个什么对象呢? 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象视图函数的 ...
- django从请求到响应的过程深入讲解
django启动 我们在启动一个django项目的时候,无论你是在命令行执行还是在pycharm直接点击运行,其实都是执行'runserver'的操作,而ruserver是使用django自带的的we ...
- Django编写RESTful API(二):请求和响应
欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...
- 【渗透课程】第二篇下-HTTP协议的请求与响应深度剖析
[渗透课程]第二篇下-HTTP协议的请求与响应深度剖析 HTTP1.1目前支持以下7种请求方法: 常见的MIME类型如下: 第一个数字有五种可能的取值: 目录 什么是请求方法?什么是请求头? HTTP ...
- Django REST FrameWork中文教程2:请求和响应
从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...
- Django学习笔记之视图高级-HTTP请求与响应
Django限制请求method 常用的请求method GET请求 GET请求一般用来向服务器索取数据,但不会向服务器提交数据,不会对服务器的状态进行更改.比如向服务器获取某篇文章的详情. POST ...
随机推荐
- CsvHelper支持List<T>
/// <summary> /// Csv帮助类 /// </summary> public class CsvHelper { /// <summary> / ...
- 各种主流浏览器CSS、BUG兼容
1.div的垂直居中问题 vertical-align:middle;将行距增加到和整个DIV一样高 line-height:200px;然后插入文字,就垂直居中了.缺点是要控制内容不要换行.---- ...
- free-简单明了解释清楚怎么看内存使用
free命令可以用来查看系统内存使用情况.我一般习惯-m参数以MB的方式查看 [root@localhost ~]# free -m total used free shared buffers ca ...
- spring ioc 源码解析
什么是ioc? 通俗的解释是:(spring)框架中,完成对象的创建和注入的容器. springIOC体系结构: spring IOC的创建是典型的工厂模式,这一系列的bean工厂如上所示. 其核心是 ...
- 关于java的格式输出控制
java中的System.out.println()功能十分强大,可以对任意类型的数据进行输出. 这里我们不讨论System.out.println(),而是讨论System.out.printf() ...
- Unix网络单词汇总
Chrome开发者工具 Elements(元素).Network(网络).Sources(源代码:调试JS的地方).Timeline(时间线).Profiles(性能分析).Resources(资源: ...
- Error:Excepted resource of type id
This inspection looks at Android API calls that have been annotated with various support annotations ...
- 修改git remote url
$ ssh -v wangz@gitlab.alibaxx-inc.com $ git remote ali set-url git@gitlab.alibaxx-inc.com:youk-aaa/x ...
- Object类.
equals方法. 比较的是内存地址.比较的是是否指向同一对象. toString:将对象转换成字符串. System.out.println()等价于 System.out.println(obj ...
- 【Tomcat】配置Tomcat
写这篇博文的原因:因为发布Maven项目的时候,始终无法访问.所以顺便重新配置了Tomcat. 1.首先到官网下载一个Tomcat7版本的zip包,解压后,放入C盘(根据个人需求放置). 2.修改co ...