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. XML解析之Jsoup

    操作xml文件 解析(读取):将文档中的数据解读到内存中 写入:将内存中的数据保存到XML文档中.持久化的存储 解析xml的方式 DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树 优点 ...

  2. mongodb定时删除数据(索引删除)

    一 简介:本文介绍创建自动删除数据的TTL索引 二 目的 定时删除数据三 创建方法   db.collection.createIndex(keys, options)   options:   ex ...

  3. DEX文件解析---1、dex文件头解析

    DEX文件解析---1.dex文件头解析 一.dex文件     dex文件是Android平台上可执行文件的一种文件类型.它的文件格式可以下面这张图概括:     dex文件头一般固定为0x70个字 ...

  4. React组件间的通讯

    组件化开发应该是React核心功能之一,组件之间的通讯也是我们做React开发必要掌握的技能.接下来我们将从组件之间的关系来分解组件间如何传递数据. 1.父组件向子组件传递数据 通讯是单向的,数据必须 ...

  5. 搭建Nginx正向代理服务

    需求背景: 前段时间公司因为业务需求需要部署一个正向代理,需要内网服务通过正向代理访问到外网移动端厂商域名通道等效果,之前一直用nginx做四层或者七层的反向代理,正向代理还是第一次配置,配置的过程也 ...

  6. 【SpringBoot | Druid】SpringBoot整合Druid

    SpringBoot整合Druid Druid是个十分强大的后端管理工具,具体的功能和用途请问阿里爸爸 1. 在pom.xml中导入包 <!-- alibaba 的druid数据库连接池 --& ...

  7. 百度下载给的termux是个坑

    termux有两个版本,0.32以及0.64.百度提供0.32的下载,太坑爹.谷歌则是0.64的下载.32版uname -m识别为armv8l,绝对影响你进行其它linux的部署.通过atilo脚本会 ...

  8. ArrayList和LinkedList的源码学习,理解两者在插入、删除、和查找的性能差异

    List的使用 List的子类 1). ArrayList 数据结构:数组 2). Vector 数据结构:数组 3). LinkedList 数据结构:循环双向链表 ArrayList .Vecto ...

  9. 16 Zabbix4.4.1系统告警“Zabbix agent is not available (for 3m)“

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 Zabbix4.4.1系统告警“Zabbix agent is not available (fo ...

  10. PostGIS 安装教程(Linux)(二)

    ##接上篇,上篇讲述了Postgresql的安装,此篇介绍postgis的安装 ##附上上篇链接:https://www.cnblogs.com/giser-s/p/11195419.html 二.安 ...