创:10_4_2017
修:
什么是web框架?
-- 本质上是socket,用户请求来,业务逻辑处理,返回处理结果
-- 包含socket或者不包含socket的框架
什么是wsgi?
-- web框架网关接口,Django、flask没有自带socket, tronado框架自带socket
-- python中有 wsgiref模块自带socket服务,在python3使用该模块会有问题
如何写一个简单的web框架?
-- 导入 wsgi模块
-- 定义主逻辑处理函数,主函数中获得请求url和定义回复请求逻辑
-- 判断URL,然后把符合要求的URL分给对应的处理函数
-- 在主函数中返回 对应函数处理结果
-- 在mian函数中实例服务对象并启动web服务
#!/usr/bin/python2 # -*- coding:utf-8 -*- from wsgiref.simple_server import make_server def home(): return ‘home‘ def index(): return ‘index‘ def RunServer(environ, start_response): start_response(‘200 ok‘, [(‘Content-Type‘, ‘text/html‘)]) print environ[‘PATH_INFO‘] url = environ[‘PATH_INFO‘] if url == ‘/home‘: return home() elif url == ‘/index‘: return index() if __name__ == ‘__main__‘: httpd = make_server(‘‘, 9999, RunServer) httpd.serve_forever() # URL每次都要判断,当URL有太多的时候,就出来很多重复代码 # 如果再加入数据库操作,就显得有点杂乱,逻辑结构混乱,如何解决? # 不妨先把URL和对应函数进行归类
上面的服务有问题,哪些问题?URL和处理函数放在了一起,有点乱
#!/usr/bin/python2 # -*- coding:utf-8 -*- from wsgiref.simple_server import make_server # 导入wsgi模块 def home(): with open(‘home.html‘, ‘r‘) as f: # 打开文件,读进来 data = f.read() return data # home逻辑处理 def index(): return ‘welcome to index‘ # index逻辑处理 URLS = { # url和函数之间通过字典建立映射关系 ‘/home‘: home, ‘/index‘: index, } def RunServer(environ, start_response): # 对请求url处理与匹配 start_response(‘200 ok‘, [(‘Content-Type‘, ‘text/html‘)]) url = environ[‘PATH_INFO‘] if url in URLS.keys(): # 判断url是否在URLS中 func = URLS[url] # 在就调用处理函数 return func() # 返回处理结果 else: return ‘404‘ # 不在返回错误404 if __name__ == ‘__main__‘: httpd = make_server(‘‘, 9999, RunServer) httpd.serve_forever() # 虽然实现了不对主逻辑函数修改,只需要修改URL字典,就可以解决匹配问题 # 逻辑结构不混乱,但是处理函数和URL过多的话,全写在一个页面,不太容易维护与阅读,如何实现? # 不妨把各自功能写在一个.py文件中,然后通过各自导入不就实现了分类,逻辑清晰? # 不妨把url写在一个url.py文件中,处理函数写在ccontrollers中,返回的html写在view目录中,不就解决这个问题了?
先建立yizhihua目录,保存目录下__init__.py文件,在yizhihua目录下面建立如下文件
- urls.py 写入
from yizhihua import controllers URLS = { # url和函数之间通过字典建立映射关系 ‘/home‘: controllers.home, ‘/index‘: controllers.index, }
- start.py 写入 -启动程序入口
#!/usr/bin/python2 # -*- coding:utf-8 -*- from wsgiref.simple_server import make_server # 导入wsgi模块 from yizhihua import urls # 导入urls模块 def RunServer(environ, start_response): # 对请求url处理与匹配 start_response(‘200 ok‘, [(‘Content-Type‘, ‘text/html‘)]) url = environ[‘PATH_INFO‘] if url in urls.URLS.keys(): # 判断url是否在URLS中 func = urls.URLS[url] # 在就调用处理函数 return func() # 返回处理结果 else: return ‘404‘ # 不在返回错误404 if __name__ == ‘__main__‘: httpd = make_server(‘‘, 9999, RunServer) httpd.serve_forever()
- controllers.py 写入 - 逻辑处理函数
from jinja2 import Template import os def home(): with open(os.path.join(‘views‘, ‘home.html‘), ‘r‘,) as f: # 打开文件,读进来 result = f.read() template = Template(result) # 实例渲染对象 data = template.render({‘user_list‘:[‘18‘, ‘beauty‘, ‘hehe‘], ‘name‘:‘yizhua‘}) # 渲染模版 return data.encode(‘utf-8‘) # 字符转码 def index(): with open(os.path.join(‘views‘, ‘index.html‘), ‘r‘) as f: # 打开文件,读进来 data = f.read() return data # index逻辑处理 # os.path.join() 把两个字符拼成路径
- view目录 ,在此目录下保存html文件,模版文件
- home.html 写入
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>home</title> 6 </head> 7 <body> 8 <h1>{{name}}</h1> 9 <ul> 10 {% for item in user_list %} 11 <li>{{ item }}</li> 12 {% endfor %} 13 </ul> 14 </body> 15 </html>
- index.html 写入
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>index页面</title> 6 </head> 7 <body> 8 <h1>index</h1> 9 </body> 10 </html>
- models.py 暂时不写入, 主要用于写数据表结构,和数据库交互
然后启动start模块,访问 http://127.0.0.1:9999/home 或 http://127.0.0.1:9999/index 获得返回的页面
框架中有哪些模块?
-- models 数据库相关操作
-- views 模版html文件
-- controllers 业务逻辑
其实是把代码进行逻辑分类,通过其中各自相互导入,实现整体性,上面是mvc框架
-- models 数据库相关处理
-- views 业务逻辑
-- Tempates 模版html文件
这个就是MTV框架,本质上和MVC一样,只是名字不一样
如何实现动态向模版中传入参数?
-- 替换一个值 自定义{{item}} ,然后通过字符替换data.replace({{item}}, ‘替换值’)
-- 循环替换
模版语言有哪些模块?
jinja2模块,模版语言
-- pip install jinja2
- 导入 from jinja2 import Template
- 把读进来的结果传给template template = Template(读进来的结果)
- 把结果渲染 data = template.render({字段1 :值1,列表 2 :列表值 2}) 字典形式
替换值: 在模版中把 {{ 字段1 }} 的位置替换成值1
循环:{% for item in 列表2 %}
{{ item }}
{% endfor %} 在模版中循环每次把列表值2放入{{ item }}的位置
- 一般写在html中,然后在逻辑函数
--渲染完成之后,后面要转码 .decode(‘utf-8’)