Django源码剖析
一、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:
首先程序会根据配置文件中:
源码截图:
找到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 源码小剖: 初探 WSGI
Django 源码小剖: 初探 WSGI python 作为一种脚本语言, 已经逐渐大量用于 web 后台开发中, 而基于 python 的 web 应用程序框架也越来越多, Bottle, Djan ...
- Django Rest Framework源码剖析(八)-----视图与路由
一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...
- Django Rest Framework源码剖析(七)-----分页
一.简介 分页对于大多数网站来说是必不可少的,那你使用restful架构时候,你可以从后台获取数据,在前端利用利用框架或自定义分页,这是一种解决方案.当然django rest framework提供 ...
- Django Rest Framework源码剖析(六)-----序列化(serializers)
一.简介 django rest framework 中的序列化组件,可以说是其核心组件,也是我们平时使用最多的组件,它不仅仅有序列化功能,更提供了数据验证的功能(与django中的form类似). ...
- Django Rest Framework源码剖析(五)-----解析器
一.简介 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数据格式,比如xml,所以需要解析这类数 ...
- Django Rest Framework源码剖析(四)-----API版本
一.简介 在我们给外部提供的API中,可会存在多个版本,不同的版本可能对应的功能不同,所以这时候版本使用就显得尤为重要,django rest framework也为我们提供了多种版本使用方法. 二. ...
- Django Rest Framework源码剖析(三)-----频率控制
一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过 ...
- Django Rest Framework源码剖析(二)-----权限
一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...
- 跨站请求伪造(csrf),django的settings源码剖析,django的auth模块
目录 一.跨站请求伪造(csrf) 1. 什么是csrf 2. 钓鱼网站原理 3. 如何解决csrf (1)思路: (2)实现方法 (3)实现的具体代码 3. csrf相关的装饰器 (1)csrf_p ...
随机推荐
- Spring MVC单选按钮
以下示例显示如何在使用Spring Web MVC框架的表单中使用单选按钮(RadioButton).首先使用Eclipse IDE来创建一个WEB工程,并按照以下步骤使用Spring Web Fra ...
- Redis快速入门及实现
redis的概念 (1)Redis的优点 以下是Redis的一些优点. 异常快 - Redis非常快,每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET) ...
- day10上节内容补充和初始函数
1.上节内容补充 文件的删除和修改: #文件的删除和修改 #文件中全部都要修改 # with open('歌词',encoding='utf-8') as f1,open('歌词.bak','w',e ...
- dva解读1
1.首先定义一个app对象实现dva const app = dva({ history: createHistory(), }); // 2. Plugins app.use(createLoadi ...
- 跟上Java8 - 日期和时间实用技巧,转自知乎王爵nice
作者:王爵nice链接:https://zhuanlan.zhihu.com/p/28133858来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 当你开始使用Java操 ...
- iOS-ASIHTTPRequest框架学习
本文转载至 http://www.cnblogs.com/A-Long-Way-Chris/p/3539679.html 前段时间在公司的产品中支持了够快网盘,用于云盘存储. 在这个过程中,学习到了很 ...
- cocos2D 虚拟摇杆Joystick功能实现
@implementation InputLayer - (id)init { if(self = [super init]) { ...
- rest规范 ; restful 风格; gradel介绍 ; idea安装 ;
[说明]上午整理了一下心情:下午继续开始任务,了解了restful,知道了那个牛人的博士论文,下载了管理工具gradle,并且部署了环境:晚上安装了idea继承环境并且建了一个简单的gradle项目( ...
- 3 Steps(二分图)
C - 3 Steps Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Rng has a ...
- 问题:Unable to find a 'userdata.img' file for ABI armeabi to copy into the AVD folder.
创建AVD时,发现创建不成功,报错“Unable to find a 'userdata.img' file for ABIarmeabi to copy into the AVD folder.” ...