本章目录:
使用Python标准库提供的独立WSGI服务器来实现MVC架构。
首先,实现一个简单的Web服务器:
from wsgiref.simple_server import make_server # 每当一个请求连接,这个函数被调用一次 def RunServer(environ, start_response): # 返回响应头、状态等 start_response('200 OK', [('Content-Type', 'text/html')]) # 返回响应体数据 return ['<h1>Hello World</h1>'.encode('utf-8'), ] def main(): # 创建一个服务器,监听端口为8000,绑定运行函数为RunServer() httpd = make_server('', 8000, RunServer) print('Servering HTTP in port 8000..') # 无线循环 httpd.serve_forever() if __name__ == '__main__': main()
添加处理URL的功能:
from wsgiref.simple_server import make_server import time # 对应'/index'的处理函数 def handle_index(): return ["<h1>Index Page...</h1>".encode('utf-8'), ] # 对应'/register'的处理函数 def handle_register(): return ["<h1>Register Page...</h1>".encode('utf-8'), ] # 对应'/date'的处理函数 def handle_date(): return [("<h1>Date:" + str(time.time()) + "</h1>").encode('utf-8'), ] # 全局字典,手工添加映射关系 URL_DICT = { '/index': handle_index, '/register': handle_register, '/date': handle_date } # 每当一个请求连接,这个函数被调用一次 def RunServer(environ, start_response): # 返回响应头、状态等 start_response('200 OK', [('Content-Type', 'text/html')]) # 检查字典中是否存在映射关系,如果有则调用对应的函数,如果没有则返回404 current_url = environ['PATH_INFO'] func = None if current_url in URL_DICT: func = URL_DICT[current_url] if func: return func() else: return ['<h1>404 Error Page..</h1>'.encode('utf-8'), ] def main(): # 创建一个服务器,监听端口为8000,绑定运行函数为RunServer() httpd = make_server('', 8000, RunServer) print('Servering HTTP in port 8000..') # 无线循环 httpd.serve_forever() if __name__ == '__main__': main()
上述代码添加了处理URL的功能,可以根据不同的URL返回不同的数据。
主要的关键点:
1.使用一个全局的字典来存放URL和处理函数之间的映射关系(注意,这里的映射关系是写死的,也就是说我们要添加一个页面,就得手工往字典中添加一个映射关系)
2.每个URL使用一个独立的函数进行处理
我们可以通过处理函数读取index.html文件中的内容,然后将其返回:
对handle_index()进行修改:
# 对应'/index'的处理函数 def handle_index(): data = b'' with open('index.html', 'rb') as f: data = f.read() return [data, ]
添加一个index.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index Page</title> </head> <body> <h1>This is @user Index Page...</h1> </body> </html>
这里的@user可以用数据库读取的内容来替换。
我们参考第一节中的代码,将其修改为MVC架构。
修改项目的目录结构,添加View、Controller和Model三个目录:
Controller:用于存放业务处理逻辑代码,例如前面的handle_index()等。功能例如读取Html文件,替换数据,返回数据等。
Model:用于存放数据库操作等代码。这些代码用于读取数据库数据,并将数据返回给Controller。
View:用于存放前端页面文件,例如Html等。主要是Html模板。
我们将index.html这类静态文件放入View目录中。
将handle处理函数全部分离到handler.py中,然后放到Controller中:
import time from Model import read_db # 对应'/index'的处理函数 def handle_index(): data = b'' with open('Template/index.html', 'rb') as f: data = f.read() user = read_db.get_user() print(user)
# 将index.html中的@user替换为从数据库中获取的数据,这里例如"Leo" data = data.replace(b"@user", user.encode('utf-8')) return [data, ] # 对应'/register'的处理函数 def handle_register(): return ["<h1>Register Page...</h1>".encode('utf-8'), ] # 对应'/date'的处理函数 def handle_date(): return [("<h1>Date:" + str(time.time()) + "</h1>").encode('utf-8'), ]
这样,将所有的文件分类放置。将整个项目划分为MVC三个层面,叫做MVC架构。
对应MVC架构,还有一种叫做MTV架构,实际上他们是一样的:
架构名称 | 数据库处理 | 模板文件 | 业务处理 |
MVC | Model | View | Controller |
MTV | Model | Template | View |
如上表所示,MVC和MTV架构只是名字的对应关系不一样。
在MTV中,html文件属于Template,而业务处理叫做View。
通过修改项目目录结构,将MVC修改为MTV结构: