Django 自带的服务器基于 python wsgiref 模块实现,Django 内置服务器在 django.core.servers 和 django.core.handlers, 这两者共同来实现.
basehttp.py 重写 ServerHandler,WSGIServer,WSGIRequestHandler,定义 run() 函数
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.
base.py application 的基类 BaseHandler
wsgi.py 实现 WSGIHandler 类, 定义了 call, 这样就名正言顺的 WSGI 中的 application 了