Django再来一遍
理解web框架
Python web程序一般分成两个部分:
- 服务器程序:对socket服务器进行封装;对请求的数据进行整理
- 应用程序:负责实现具体的逻辑
应用程序一定会有很多种,但是服务器程序一定要配合应用程序,那么有几个应用程序就要有几种服务器程序吗。
让服务器可以支持更多框架,框架也能更多支持标准的服务器,出现了WSGI(web sever gateway interface)
定义了使用Python编写web app和web server之间的接口格式。
用分析一个小程序,来理解框架中url和views之间的协作过程。
from wsgiref.simple_server import make_server
def index():
return 'index'
# 定义一个index函数,用于返回字符串index
def login():
return 'login'
def routers():
# 一个路由函数,里面保存了路径和运行函数的对应元组,返回值为所有对应元组的集合元组;
# 眼熟吗,是不是很像urls.py里面的:
"""
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^all/(?P<type_id>d+)/', views.index),
# 通过url的别名传递type_id给后台
url(r'^login.html', views.login),
url(r'^check_code/', views.check_code),
url(r'^', views.index),
]
"""
urlpatterns = (
('/index/',index),
('/login/',login),
)
return urlpatterns
def RunServer(environ, start_response):
# 响应runserver中传入的这两个参数分别代表什么?一个字典,一个函数名
start_response('200 OK', [('Content-Type', 'text/html')])
# 响应
url = environ['PATH_INFO']
# 将path_info获取为url,实际上path_info这个参数的确也可以获得url
urlpatterns = routers()
#获取路由路径元组
func = None
# 在全局设置一个func变量,暂时为None
for item in urlpatterns:
if item[0] == url:
func = item[1]
break
# 在路由元组中匹配获得的url,如果匹配成功就break,获取到对应的func值
if func:
return func()
# func值存在的时候,就运行对应的函数 ------views.app
else:
return '404 not found'
# 否则就报错不存在
if __name__ == '__main__':
httpd = make_server('', 8000, RunServer)
print "Serving HTTP on port 8000..."
httpd.serve_forever()
上面的小程序,index函数和login函数返回的仅仅是简单的字符串,但是实际应用中,应该返回的是一个具体的页面(“复杂的符合HTML规则的字符串”)。并且这个页面被放在指定的文件夹中。
这时候需要改写一下:
def index():
f=open('index.html')
data=f.read()
return data
做到这一步,我们已经能给用户返回静态的html内容了。如何给用户返回动态的内容?
- 自定义一套特殊的语法,进行替换
- 使用开源工具jinja2,遵循指定语法
from wsgiref.simple_server import make_server
from jinja2 import Template
# 眼熟吗系列,这个tamplate是Django里面的那个tamplate吗
def index():
# return 'index'
# template = Template('Hello {{ name }}!')
# 这条注释是用来表示在jinja中的前端页面,使用什么语法来获得后端返回数据的。
# result = template.render(name='John Doe')
f = open('index.html')
result = f.read()
#读取html页面的内容
template = Template(result)
# 实例化一个Template,内容就是刚才读取的页面
data = template.render(name='John Doe', user_list=['alex', 'eric'])
# 利用Template类中的render方法(眼熟吗)传入两个变量(其实这种xx=zz的形式不是可以看成是字典吗)
return data.encode('utf-8')