Django源码分析之server
乍见
Django内置的server基本包括两部分:django.core.servers和django.core.handlers
相识
servers.basehttp是Django自身提供的一个用于开发测试的server模块,其中提供的WSGIServer、ServerHandler、WSGIRequestHandler其实都是属于WSGI server,django只不过是对python内置的WSGI模块simple_server做的一层包装。
handlers package包括base.py和wsgi.py两个模块。
base.py中只定义了一个BaseHandler类,它复杂一些基础的功能,比如加载中间件,处理异常,获取响应数据等
wsgi.py才是主角,其中最重要的就是WSGIHandler类,它继承了base.py中的BaseHandler,只添加了一个__call__方法,那为什么添加这个方法呢?
django.core.wsgi
import django
from django.core.handlers.wsgi import WSGIHandler
def get_wsgi_application():
    """
    The public interface to Django's WSGI support. Should return a WSGI
    callable.
    Allows us to avoid making django.core.handlers.WSGIHandler public API, in
    case the internal WSGI implementation changes or moves in the future.
    """
    django.setup()
    return WSGIHandler()
可见我们启动server时传入的application其实是WSGIHandler的一个实例,而根据WSGI规范,这个application必须要是callable,python中的callable包括函数、方法以及任何定义了__call__方法的对象
回到handlers.wsgi
class WSGIHandler(base.BaseHandler):
    initLock = Lock()
    request_class = WSGIRequest
    def __call__(self, environ, start_response):
        # Set up middleware if needed. We couldn't do this earlier, because
        # settings weren't available.
        if self._request_middleware is None:
            with self.initLock:
                try:
                    # Check that middleware is still uninitialized.
                    if self._request_middleware is None:
                        self.load_middleware()
                except:
                    # Unload whatever middleware we got
                    self._request_middleware = None
                    raise
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)
        try:
            request = self.request_class(environ)
        except UnicodeDecodeError:
            logger.warning('Bad Request (UnicodeDecodeError)',
                exc_info=sys.exc_info(),
                extra={
                    'status_code': 400,
                }
            )
            response = http.HttpResponseBadRequest()
        else:
            response = self.get_response(request)
        response._handler_class = self.__class__
        status = '%s %s' % (response.status_code, response.reason_phrase)
        response_headers = [(str(k), str(v)) for k, v in response.items()]
        for c in response.cookies.values():
            response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
        start_response(force_str(status), response_headers)
        if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
            response = environ['wsgi.file_wrapper'](response.file_to_stream)
        return response
由于__call__是一个请求的入口,它需要调用BaseHandler中定义的方法去执行加载中间件等一系列操作和异常处理,除此之外,WSGIHandler还会处理cookie、触发signal等。
至于如何返回响应,具体可看handlers.base模块,大概就是找出请求的path,通过匹配路由,找到并执行用户定义的view方法,执行中间件处理方法,最后返回响应。当然,还有一系列的异常处理。
回想
这部分的内容需要对WSGi协议有个大致的了解,可以参考:http://xiaorui.cc/2016/04/16/%E6%89%93%E9%80%A0mvc%E6%A1%86%E6%9E%B6%E4%B9%8Bwsgi%E5%8D%8F%E8%AE%AE%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9%E5%8F%8A%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0/
Django源码分析之server的更多相关文章
- django源码分析 python manage.py runserver
		django是一个快速开发web应用的框架, 笔者也在django框架上开发不少web应用,闲来无事,就想探究一下django底层到底是如何实现的,本文记录了笔者对django源码的分析过程 I be ... 
- Django源码分析之启动wsgi发生的事
		前言  好多人对技术的理解都停留在懂得使用即可,因而只会用而不会灵活用,俗话说好奇害死猫,不然我也不会在凌晨1.48的时候决定写这篇博客,好吧不啰嗦了  继续上一篇文章,后我有个问题(上文:&qu ... 
- django源码分析——本地runserver分析
		本文环境python3.5.2,django1.10.x系列 1.根据上一篇文章分析了,django-admin startproject与startapp的分析流程后,根据django的官方实例此时 ... 
- 2、Django源码分析之启动wsgi发生了哪些事
		一 前言 Django是如何通过网络socket层接收数据并将请求转发给Django的urls层? 有的人张口就来:就是通过wsgi(Web Server Gateway Interface)啊! D ... 
- Apache Kafka源码分析 – Broker Server
		1. Kafka.scala 在Kafka的main入口中startup KafkaServerStartable, 而KafkaServerStartable这是对KafkaServer的封装 1: ... 
- Kafka源码分析(三) - Server端 - 消息存储
		系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 业务模型 1.1 概念梳理 1.2 文件分析 1.2.1 数据目录 1.2.2 . ... 
- django源码分析
		原文网址 https://www.jianshu.com/p/17d78b52c732?utm_campaign=maleskine&utm_content=note&utm_medi ... 
- django源码分析——处理请求到wsgi及视图view
		本文环境python3.5.2,django1.10.x系列 根据前上一篇runserver的博文,已经分析了本地调试服务器的大致流程,现在我们来分析一下当runserver运行起来后,django框 ... 
- kafka源码分析之一server启动分析
		0. 关键概念 关键概念 Concepts Function Topic 用于划分Message的逻辑概念,一个Topic可以分布在多个Broker上. Partition 是Kafka中横向扩展和一 ... 
随机推荐
- 【luogu P3378 堆】 模板
			题目链接:https://www.luogu.org/problemnew/show/P3378 是堆的模板...我懒,STL da fa is good #include <iostream& ... 
- HTML5之转动的轮子
			<!doctype html><html> <head></head> <body> <canvas width="1000 ... 
- 关闭Debut.Log
			unity5.3支持了运行时关闭产生的debug.log Debug.logger.logEnabled = false; 谢谢你们,让我能在晚上凝视夜空的时候,脑海中浮现出更广阔的世界. 
- papers-06-02
			午睡被同事吵醒,只好干活.看到微信公众号有一篇文章说老朋友呢,点进去发现原来相关的工作好多,而且好新好细致. 微信的文章可以见这里: 探究最陌生的老朋友Softmax 里面的几篇文章可以看看. Lar ... 
- ProjectServer任务审批后自动发布
			我们知道ProjectServer汇报工时的顺序是这样: 1.项目成员打开自己的时间表,选择要汇报的任务,在汇报工时栏填写实际工时. 2.汇报工时后点击保存. 3.将汇报工时的任务提交给项目经理. 4 ... 
- TCP协议与UDP协议
			网络通信协议规定了网络通信时,数据必须采用的格式.常见的协议有TCP协议,UDP协议. TCP协议 :(Transmission Control Protocol)传输控制协议. TCP是一种面向连接 ... 
- WebGL学习笔记(2)
			根据上一篇学习笔记,理解WebGL的工作原理及基本调用代码后,可以开始研究3D顶点对象的缩放.旋转.以及对对象进行可交互(鼠标或键盘控制)的旋转或者缩放. 要理解对象的旋转/缩放需要首先学习矩阵的计算 ... 
- [USACO08NOV]时间管理Time Management(排序,贪心)
			题目描述 作为一名忙碌的商人,约翰知道必须高效地安排他的时间.他有N工作要 做,比如给奶牛挤奶,清洗牛棚,修理栅栏之类的. 为了高效,列出了所有工作的清单.第i分工作需要T_i单位的时间来完成,而 且 ... 
- Python3集成安装xadmin
			Python3集成安装xadmin1:创建虚拟环境C:\Users\Adminstrator>mkvirtualenv -p C:\Python34\python.exe MyDjango如果提 ... 
- mysql 导出数据字典
			使用Navicat工具 查询: SELECT TABLE_SCHEMA AS '数据库', TABLE_NAME AS '表名', COLUMN_NAME AS '字段名', COLUMN_TYPE ... 
