1. 命令行启动

命令行是通过runserver子命令来启动的,对应的django模块为django.core.management.commands.runserver,调用关系结构:

# 简化的运行代码:
django.core.management.commands.runserver.py class Command:
def get_handler():
return django.core.servers.basehttp.get_internal_wsgi_application() def run: # 命令行如果函数
self.run_inner() def run_inner():
handler = self.get_handler()
django.core.servers.basehttp.run(..., handler, ...) django.core.servers.basehttp.py
def get_internal_wsgi_application():
1. settings.WSGI_APPLICAITON
2. 上面的配置不存在,则执行:
django.core.wsgi.get_wsgi_application() def run():
启动http服务,监听端口,注册WSGI django.core.wsgi.py
def get_wsgi_application():
django.setup()
return django.core.handlers.wsgi.WSGIHandler() django.core.handlers.wsgi.py
class WSGIHandler(base.BaseHandler):
def __init__():
self.load_middleware() # 装载了中间件 def __call__(self, environ, start_response): # 请求的入口函数
pass

2. web服务器启动

Web服务器配置:
WSGIScriptAlias / /my/web/site/site/wsgi.py site/wsgi.py # 这个文件默认是与settings.py同级
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE", 'site.settings')
application = get_wsgi_applicaiton() application变量的获取与命令行最后部分是一致的。

3. 核心

这个核心函数的处理内容:
django.core.wsgi.WSGIHandler.__call__(self, environ, start_response)
1. 发送一个信号
2. 处理请求、处理中间件
3. 处理响应
4. 调用start_response返回响应头
5. 返回响应体 __call__ 函数的特点:
1. 每次请求的入口函数
2. 这个函数内部代码都属于请求过程,也就是线程工作空间

4. 自定义 WSGI 思路

关键在于自定义 get_wsgi_applicaiton函数:
1. 根据代码,我认为可以在 settings 中配置 WSGI_APPLICATION 的方式来定义该函数,这个可能只能解决命令行启动问题
2. web服务器启动的时候,因为 site/wsgi.py 文件属于站点独立文件,我们其实可以自己重新这个文件的,这样很容易调用到自己定义的 get_wsgi_application() 函数
3. get_wsgi_applicaiton() 函数的返回值 设置为自己实现的 WSGIHandler() 就可以实现自己的 WSGI了。
4. 在 WSGIHandler 的 __call__ 方法内,定义一些全局变量,这个变量将属于整个线程,并且可以在各关联函数内使用,比如给
signals增加一个request 属性,则可以在所有 signal receiver函数内访问到这个属性了。
def __call__(...):
setattr(signals, 'request', request)

5. 另外一种方法

这个方法的关键在于提供一个 middleware,然后在 middleware 的process_request 方法内,给一个公共模块设置属性的值,
这样这个属性的值在各模块内都是可访问的。 class MyMiddleware(MiddlewareMixin):
def process_request(self, request):
setattr(signals, 'request', request) def my(sender, **kwargs):
if hasattr(signals, 'request'):
print(singals.request) request_started.connect(my, sender=WSGIRequest) 这个方式不是线程安全的,signals对象属于进程变量,在所有现在内共享。可以考虑使用threading.local技术来实现线程安全的请求变量赋值。

[TimLinux] django WSGI入口分析及自定义WSGIHandler思路的更多相关文章

  1. django源码分析——处理请求到wsgi及视图view

    本文环境python3.5.2,django1.10.x系列 根据前上一篇runserver的博文,已经分析了本地调试服务器的大致流程,现在我们来分析一下当runserver运行起来后,django框 ...

  2. python web框架 django wsgi 理论

    django wsgi python有个自带的wsgi模块 可以写自定义web框架 用wsgi在内部创建socket对象就可以了 自己只写处理函数就可以了django只是web框架 他也不负责写soc ...

  3. Spring Ioc源码分析系列--Ioc源码入口分析

    Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...

  4. MongoDB源码分析——mongo主程序入口分析

    Edit   源码版本为MongoDB 2.6分支 mongo主程序入口分析 mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,可以用来和服务端交互,2.6版本的Mongo ...

  5. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  6. 开源GUI-Microwindows之程序入口分析

    **************************************************************************************************** ...

  7. asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证

    原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 在前面的文章中我们曾经涉及到ControllerActionInvoker类GetPara ...

  8. Android 短信模块分析(三) MMS入口分析

    MMS入口分析:      在Mms中最重要的两个Activity,一个是conversationList(短信列表) ,另一个就是ComposeMessageActivity(单个对话或者短信).每 ...

  9. 强大的django-debug-toolbar,django项目性能分析工具

    强大的django-debug-toolbar,django项目性能分析工具 给大家介绍一个用于django中debug模式下查看网站性能等其他信息的插件django-debug-toolbar 首先 ...

随机推荐

  1. java jar包在dos框运行步骤演练

    1.选择需要打包的   java project 2.右击,    选择export点击 , 3 选择java选项中的jar file选项 , 点击下一步 4 确认你需要的打包的项目, 点击下一步 5 ...

  2. PHP实现微信企业付款到个人零钱步骤

    微信支付企业付款到零钱功能应用广泛,比如微信红包奖励,业务结算等.通过企业向个人付款,付款资金将直接进入用户微信零钱. 一 开通条件 ​ 付款资金 企业付款到零钱资金使用商户号余额资金. 根据商户号的 ...

  3. 通过canvas合成图片

    通过canvas合成图片 效果图 页面布局部分 两个图片以及一个canvas画布 <img src="https://qnlite.gtimg.com/qqnewslite/20190 ...

  4. nyoj 10 skiing (DFS)

    skiing 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当 ...

  5. asp.net以流导出Excel

    废话不多说,直接上代码 这是点击导出的事件函数,因为我是从前端获取的Table的json数据,所以需要转换一下,大家直接用查询出来的DataTable即可 protected void bt_expo ...

  6. SpringBoot Application深入学习

    本节主要介绍SpringBoot Application类相关源码的深入学习. 主要包括: SpringBoot应用自定义启动配置 SpringBoot应用生命周期,以及在生命周期各个阶段自定义配置. ...

  7. 勾股数专题-SCAU-1079 三角形-18203 神奇的勾股数(原创)

    勾股数专题-SCAU-1079 三角形-18203 神奇的勾股数(原创) 大部分的勾股数的题目很多人都是用for来便利,然后判断是不是平方数什么什么的,这样做的时候要对变量类型和很多细节都是要掌握好的 ...

  8. Android 8.1 自定义热点的时候设置了热点maxLength="32",但是在希伯来语等状态下还是发现在没到32个字符之前就无法把热点设置成功了

    初步认为应该是与热点名称的字节数有关. 然后开始查看源码. /Settings/res/xml/tether_prefs.xml 中的 <Preference android:key=" ...

  9. MySQL常用的查询语句回顾

    让你快速复习语句的笔记宝典. create table users(    username varchar(20) primary key,    userpwd varchar(20) ) alt ...

  10. 学会这8个优秀 Python 库用于业余项目,将大大减少程序员耗费的精力

    在数据库中即时保存数据:Dataset 当我们想要在不知道最终数据库表长什么样的情况下,快速收集数据并保存到数据库中的时候,Dataset 库将是我们的最佳选择.Dataset 库有一个简单但功能强大 ...