今天学习了一下用简单的Django框架与简单的WSGI服务器配套运行一个简单的Django项目;
Django不是完整的web后端框架,它需要和一个WSGI服务器配套,由WSGI服务器负责网络通讯部分。
1.Django与WSGI
WSGI全称:Web Server Gateway Interface,是Python定义的WSGI程序和WSGI服务器之间的一种接口
现一个WSGI应用,只需要满足3个要求:
- 是可调用的,比如是一个函数,或者是一个可调用类(具有__call__方法)的实例
- WSGI应用应当返回一个可迭代(iterable)的值,比如字符串列表
- WSGI应用在返回之前,应当调用WSGI服务器传入的start_response函数发送状态码和HTTP报文头
一种最简单的满足WSGI规约的应用程序需要实现一个指定形式的函数:
from wsgiref.simple_server import make_server def wsgi_app(environ,start_response): from pprint import pprint pprint(environ) start_response(‘200 OK‘,[(‘Context-Type‘,‘text/plain‘)]) return ‘such a tiny wsgi app!‘ httpd = make_server(‘0.0.0.0‘,80,wsgi_app) print ‘start server‘ httpd.serve_forever()
environ是一个包含全部HTTP请求信息的字典/Dict,由WSGI服务器解包HTTP请求生成。
2.创建WSGI应用对象:
Django框架对一个WSGI应用的结构进行了分解,有些部件由框架完成,有些部分需要 开发者实现。因此,开发一个基于Django框架的Web应用,事实上就是填充Django框架 所约定的需要由开发者完成的部件。
根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图。Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理:
Django框架严重依赖于一个全局配置对象settings来定制 其行为,因此,我们需要在创建WSGI应用对象之前,首先使用默认值初始化这个全局 配置对象
from django.conf import settings;#配置对象 from django.core.wsgi import get_wsgi_application; #创建WSGI应用对象 settings.configure() settings.DEBUG = True #配置对象 wsgi_app = get_wsgi_application(); #创建WSGI应用对象 print wsgi_app
3.编写视图函数
输入 :第一个参数是一个HttpRequest对象,这是Django框架对一个HTTP请求 的完整封装,视图函数从这个对象中提取请求中的信息
输出 :返回值应当是一个HttpResponse对象,Django框架将基于这个返回 的对象完成对WSGI服务器的响应
from django.conf import settings from django.core.wsgi import get_wsgi_application from django.http import HttpRequest,HttpResponse settings.configure() settings.DEBUG = True wsgi_app = get_wsgi_application() #一个简单的视图函数 def v_index(request): return HttpResponse(‘Hello,Djando!‘) #模仿框架构造一个HttpRequest对象,传给视图函数 req = HttpRequest(); print v_index(req)
4.定义路由表
Django框架根据HTTP请求的URL来找到对应的视图函数,很自然的,路由表 使用一个列表对象,其中每一项记录一种URL模式与一个视图函数的对应关系;
url()函数用来生成一个路由项,第一个参数是一个正则表达式,用来匹配 HTTP请求的URL,前缀r用来防止正则字符串被转义;第二个参数就是我们定义 的视图函数。
注册路由:
在一个有点规模的应用中,可能会存在多个开发组,每个开发组维护单独的一张路由表。 因此,在Django框架中,需要告诉Django框架使用那个路由表作为根路由表。
使用全局配置对象的ROOT_URLCONF属性来注册根路由表,应当为这个属性指定一个 具有urlpatterns变量的模块名,Django将动态导入这个模块并使用其urlpatterns 变量的值作为路由表。
因此,通常情况下,总应该将路由表变量命名为urlpatterns。
import sys from django.conf import settings from django.core.wsgi import get_wsgi_application from django.http import HttpRequest,HttpResponse from django.conf.urls import url settings.configure() settings.DEBUG = True wsgi_app = get_wsgi_application() def v_index(request): return HttpResponse(‘Hello,Djando!‘) urlpatterns = [ url(r‘^$‘,v_index), ] settings.ROOT_URLCONF = sys.modules[__name__] print urlpatterns
5.对接简单WSGI服务器:
使用python自带的简单WSGI服务器:
from wsgiref.simple_server import make_server httpd = make_server(‘0.0.0.0‘,80,wsgi_app)#全地址0.0.0.0;端口号80 httpd.serve_forever()
6.最后生成一个用Django实现WSGI应用程序:
# -*- coding:utf-8 -*- import sys from django.conf import settings from django.core.wsgi import get_wsgi_application from django.http import HttpRequest,HttpResponse from django.conf.urls import url from wsgiref.simple_server import make_server settings.configure() settings.DEBUG = True wsgi_app = get_wsgi_application() def v_index(request): return HttpResponse(‘Hello,Djando!‘) urlpatterns = [ url(r‘^$‘,v_index),#r为防止正则字符串被转义,‘^$‘中Django框架在使用定义的路由表之前,已经吃掉了$符前的那个前缀的/ ] settings.ROOT_URLCONF = sys.modules[__name__] httpd = make_server(‘0.0.0.0‘,80,wsgi_app) print ‘starting server...‘ httpd.serve_forever()