Django 其内部已经自带了一个方便本地测试的小服务器, 所以在刚开始学习 Django 的时候并不需搭建 apache 或者 nginx 服务器. Django 自带的服务器基于 python wsgiref 模块实现的, 其百分之七八十的代码都是 wsgiref 中的代码, 只重写了一部分, 所以 Django 自带的服务器测试写个 helloworld 就好了.

Django 内置服务器在 django.core.servers 和 django.core.handlers, 这两者共同来实现.先看看 django.core.servers. 下面是目录结构:

E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\SERVERS
basehttp.py 重写 ServerHandler,WSGIServer,WSGIRequestHandler,定义 run() 函数
fastcgi.py
__init__.py

下面的代码足以说明「百分之七八十」:

class ServerHandler(simple_server.ServerHandler, object):
...
class WSGIServer(simple_server.WSGIServer, object):
...
class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):

具体内部做了一些变更:

  • 重写了 write 函数, 当传输数据过大的时候分段传输
  • 多了一些异常处理
  • 错误记录

都是无关痛痒, 不详细展开了.这里定义了一个很有意思的函数 run():

def run(addr, port, wsgi_handler, ipv6=False, threading=False):
server_address = (addr, port) if threading:
httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})
else:
httpd_cls = WSGIServer httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
httpd.set_app(wsgi_handler)
httpd.serve_forever() 永久运行

这和上一篇 if __name__ == '__main__': 中的代码效果类似, 实例化服务器类, 让它跑起来. 在 run() 函数中可以根据喜好配置:

add: 地址, 可传入 ip 地址, 一般是 127.0.0.1

port: 端口, 自定义端口

wsgi_handler: 上节提到的 application, 在 django.core.handlers 中定义

ipv6: 如果为 true, 会将协议地址族换成是 AF_INET6

threading: 如果为 true, 服务器会被强制成 type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})(这个我漏讲了, 但功能是这样), 能处理多线程处理请求.

所以, 调用这个函数可以让一个自定义服务器跑起来.

wsgi_handler 参数定义了 application, 而 application 必须是一个 start_response(status, response_headers, exc_info=None) 形式的函数或者定义了 __call__ 的类. 而 django.core.handlers 就用后一种方式实现了 application.

E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\HANDLERS
base.py application 的基类 BaseHandler
wsgi.py 实现 WSGIHandler 类, 定义了 __call__, 这样就名正言顺的 WSGI 中的 application 了
__init__.py

事实上, 在 WSGI 中除了 application,server 外, 还有一个 middleware, 名曰中间件. 在上一篇中故意漏了, 因为没有涉及到.最后我疏离一下上边提到的类模块等等, 方便大家找源码, 整理如下:

C:\PYTHON27\LIB\WSGIREF
handlers.py 定义了 BaseHandler, SimpleHandler 类
headers.py
simple_server.py 定义了 ServerHandler, WSGIRequestHandler 类, demo_app(), make_server()
util.py
validate.py
__init__.py

E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\SERVERS
basehttp.py 重写 ServerHandler,WSGIServer,WSGIRequestHandler,定义 run() 函数
fastcgi.py
__init__.py

E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\HANDLERS
base.py application 的基类 BaseHandler
wsgi.py 实现 WSGIHandler 类, 定义了 __call__, 这样就名正言顺的 WSGI 中的 application 了
__init__.py

ps: 目录根据实际情况会不同, 看具体情况.我已经在 github 备份了 Django 源码的注释: Decode-Django, 有兴趣的童鞋 fork 吧.

捣乱  2013-9-6

http://daoluan.net

最新文章

  1. 关于call和apply函数的区别及用法
  2. less
  3. com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files
  4. AMD正式公布第七代桌面级APU AM4新接口
  5. ACM:统计难题 解题报告-字典树(Trie树)
  6. 微软BI 之SSIS 系列 - 在 SSIS 中导入 ACCESS 数据库中的数据
  7. go2shell的安装与修改默认terminal方法
  8. 交换排序—冒泡排序(Bubble Sort)
  9. Redis Key 命令
  10. U6会计科目导入致对账不平
  11. 学渣也要搞 laravel(1)—— 安装篇
  12. Redis实现高并发分布式序列号
  13. IOC容器Unity的使用及独立配置文件Unity.Config
  14. OpenStack(企业私有云)万里长征第六步——OpenStack网络及虚拟机存储位置
  15. MySQL多Text字段报8126错误(解决过程)
  16. (NO.00003)iOS游戏简单的机器人投射游戏成形记(十四)
  17. Android学习之Button按钮在程序运行时全部变大写的处理
  18. postgrepsql 创建函数
  19. idea 常见快捷键记录下
  20. 【liunx】telnet命令

热门文章

  1. bzoj4946: [Noi2017]蔬菜 神烦贪心
  2. loj#2552. 「CTSC2018」假面
  3. Python3练习题系列(06)——各种符号总结
  4. Cesiumjs初学第一天
  5. 2016/2/26Android实习笔记(Android签名和aapt)
  6. zookeepercli - Command Line Interface for ZooKeeper
  7. redis源码分析
  8. 一道面试题 包含了new的细节 和运算符的优先级 还有属性访问机制
  9. 使用 IntraWeb (33) - Cookie
  10. 各种组件的js 获取值 / js动态赋值