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服务器之间的一种接口,已经被广泛接受, 它已基本达成它的可移植性方面的目标。

WSGI 没有官方的实现, 因为WSGI更像一个协议. 只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行, 反之亦然。
  我们今天要讲的django web框架就需要使用wsgi,djano内部并没有实现socket,而是通过socket实现的。

概述:

  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底层剖析之一次请求到响应的整个流程的更多相关文章

  1. Django:学习笔记(4)——请求与响应

    Django:学习笔记(4)——请求与响应 0.URL路由基础 Web应用中,用户通过不同URL链接访问我们提供的服务,其中首先经过的是一个URL调度器,它类似于SpringBoot中的前端控制器. ...

  2. 第一个Django应用 - 第一部分:请求与响应

    一. 新建项目 进入你期望的项目保存目录,运行下面的命令: $ django-admin startproject mysite 这将在目录下生成一个mysite目录,也就是你的这个Django项目的 ...

  3. Django:(03)请求和响应

    一.HttpRequest 客户端传参的几种方式 传递方式 示例 后端获取方式 数据类型 url路径(path) /news/1/2 正则匹配 str 查询字符串 /news2?category=1& ...

  4. python的Web框架,Django框架中的请求与响应

    请求与响应 简单流程图 我们先来了解一个请求与响应的大概流程  视图函数接受到的request到底是个什么对象呢? 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象视图函数的 ...

  5. django从请求到响应的过程深入讲解

    django启动 我们在启动一个django项目的时候,无论你是在命令行执行还是在pycharm直接点击运行,其实都是执行'runserver'的操作,而ruserver是使用django自带的的we ...

  6. Django编写RESTful API(二):请求和响应

    欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...

  7. 【渗透课程】第二篇下-HTTP协议的请求与响应深度剖析

    [渗透课程]第二篇下-HTTP协议的请求与响应深度剖析 HTTP1.1目前支持以下7种请求方法: 常见的MIME类型如下: 第一个数字有五种可能的取值: 目录 什么是请求方法?什么是请求头? HTTP ...

  8. Django REST FrameWork中文教程2:请求和响应

    从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...

  9. Django学习笔记之视图高级-HTTP请求与响应

    Django限制请求method 常用的请求method GET请求 GET请求一般用来向服务器索取数据,但不会向服务器提交数据,不会对服务器的状态进行更改.比如向服务器获取某篇文章的详情. POST ...

随机推荐

  1. Material Design

    4.适应性设计 底层设计系统包括了交互和空间两部分.每一个设备都能反映出同一底层系统的不同侧面.每一设备的界面都会按照大小和交互进行调整.只有颜色,图标,层次结构和空间关系保持不变. 它不仅仅为了好看 ...

  2. 初学Vue2.0--基础篇

    概述: 鉴于本人初学,使用的编译器是webStorm,需添加对VUE的支持,添加方法可以参考 http://www.jianshu.com/p/142dae4f8b51. 起步: 1. 扎实的 Jav ...

  3. Html中<font>标签的使用

    Html中<font>标签的使用 <!doctype html> <html lang="en"> <head> <meta ...

  4. win7系统的右键菜单只显示一个白色框不显示菜单项 解决办法

    如上图所示,桌面或其他大部分地方点击右键菜单,都只显示一个白色框,鼠标移上去才有菜单项看,并且效果很丑 解决办法: 计算机-右键-属性-高级-性能-设置-视觉效果-淡入淡出或滑动菜单到视图,将其前面的 ...

  5. C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  6. Nginx+Php Windows部署

    http://www.cnblogs.com/huayangmeng/archive/2011/06/15/2081337.html 一定要以下面的形式启动php-cgi php-cgi.exe -b ...

  7. Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

    文件的hash指纹通常作为前端静态资源实现增量更新的方案之一,Webpack是目前最流行的开源编译工具之一,其强大的功能也带来很多坑(当然,大部分麻烦其实都可以在官方文档中找到答案). 比如,在Web ...

  8. 初识virtual memory

    一.先谈几个重要的东西 virtual memory是一个抽象概念,书上的原文是"an abstraction of main memory known as virtual memory& ...

  9. 引入DecimalFormat类进行数字格式化操作

    引入语句:import java.text.DecimalFormat; 首先创建DecimalFormat类对象,利用类对象调用Format()方法进行格式化操作.这里有两种方法:①.Decimal ...

  10. php文件锁

    前言 1.锁机制之所以存在是因为并发问题导致的资源竞争,为了确保操作的有效性和完整性,可以通过锁机制将并发状态转换成串行状态.作为锁机制中的一种,PHP 的文件锁也是为了应对资源竞争.假设一个应用场景 ...