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生成RSS源
下面的示例演示如何使用Spring Web MVC框架生成RSS源. 首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: 创建 ...
- 嵌入式开发之davinci--- 8168 总的roi 编码
http://bbs.61dsp.com/forum.php?mod=viewthread&tid=767
- Java Web -- Servlet(1) 必备知识
学习Java WEB开发必备的基本概念: 1.WEB 本意是蜘蛛网和网的意思.在网页设计中我们称为网页的意思. 现广泛译作网络.互联网等技术领域.表现为三种形式,即超文本(hypertext).超媒体 ...
- C++11写算法之插入排序
插入排序,是指将从1 –> size-1的数一个个插入到前面已经排序好的数组中. 时间复杂度:O(n^2) , O(nlgn) (lgn指使用二分查找插入点位置) 空间复杂度:O(1) // ...
- SQL Server 阻止了对组件“Ad Hoc Distributed Queries”的 STATEMENT“OpenRowset/OpenDatasource”的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用“Ad Hoc Distributed Queries”。有关启用“Ad Hoc Distributed Queries”
1.开启Ad Hoc Distributed Queries组件,在sql查询编辑器中执行如下语句: exec sp_configure reconfigure exec sp_configure r ...
- Android无线测试之—UiAutomator UiSelector API介绍之二
Android的布局与组件及组件属性介绍 一.布局: 1)线性布局:控价在线性方向上一次排列 2)表格布局:向表格一样有标准的行和列 3)相对布局:通过相对定位的方式让控件出现在布局的任何位置 4)帧 ...
- [Spring Data MongoDB]学习笔记--牛逼的MongoTemplate
MongoTemplate是数据库和代码之间的接口,对数据库的操作都在它里面. 注:MongoTemplate是线程安全的. MongoTemplate实现了interface MongoOperat ...
- codevs 必做:堆:1245、2879 并查集:1069、1074、1073
1245 最小的N个和 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 有两个长度为 N ...
- [Noip2016]天天爱跑步 LCA+DFS
[Noip2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时上线,完成打卡任 ...
- Sharepoint server 2016自定义作业不能部署
最近帮客户部署SharePoint server 2016生产环境,自定义作业总是不能部署上,原来我在部署过程中MinRole选的是Web前端服务器:经过几天的测试研究,发现要有single serv ...