Web框架基础与实现
-
Web框架的核心概念 ========== Web框架本质上是一个功能强大的Socket服务端,浏览器作为具有图形界面的Socket客户端。通过网络请求进行数据交互,可以将Web框架视为前端和数据库的全面整合。
-
手动构建简易Web框架 ============= 2.1 回顾 - HTTP协议
以下代码展示了一个基本的TCP服务器,但无法响应HTTP请求:
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9000))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024)
print(data.decode('utf-8'))
conn.send(b'hi, here is server')
原因:未遵循HTTP协议。
2.2 简易Web框架实现
以下是遵循HTTP协议的简易Web服务器:
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9009))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024).decode('utf-8')
print(data)
conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n')
path = data.split()[1]
if path == '/login':
conn.send(b'Login page exists.')
elif path == '/register':
conn.send(b'Register page exists.')
else:
conn.send(b'Page not found.')
- 基于WSGI模块构建Web框架 ===================== 3.1 基础版
from wsgiref.simple_server import make_server
def app(env, start_response):
start_response("200 OK", [('Content-Type', 'text/html')])
return [b"Hello from server."]
if __name__ == "__main__":
httpd = make_server('127.0.0.1', 9002, app)
httpd.serve_forever()
3.2 完整版
from wsgiref.simple_server import make_server
def app(env, start_response):
start_response("200 OK", [])
path = env.get("PATH_INFO")
if path == "/":
return [b"Empty path."]
elif path == "/login":
return [b"Login exists."]
else:
return [b"404 error."]
if __name__ == "__main__":
httpd = make_server('127.0.0.1', 9000, app)
httpd.serve_forever()
- WSGI优化 ============ 4.1 问题分析
当网站路径增多时,代码会变得冗长且难以维护。
4.2 函数优化
将路径映射和功能封装为元组和函数:
from wsgiref.simple_server import make_server
def login():
return "Login page."
def register():
return "Register page."
def error():
return "Error page."
url_patterns = (("/login", login), ("/register", register))
def app(env, start_response):
start_response("200 OK", [])
path = env.get("PATH_INFO")
func = None
for url, handler in url_patterns:
if path == url:
func = handler
break
res = func() if func else error()
return [res.encode("utf-8")]
if __name__ == "__main__":
httpd = make_server('127.0.0.1', 9000, app)
httpd.serve_forever()
4.3 模块优化
将功能拆分为多个文件:
urls.py存储路径映射。views.py编写业务逻辑。
4.4 HTML文件优化
创建templates文件夹存储HTML文件,避免代码混乱。
4.5 静态资源优化
创建static文件夹存储CSS、JS等静态资源。
- 动静结合的网页 ======== 5.1 动静网页的区别
静态网页内容固定,动态网页根据用户请求生成内容。
5.2 示例:显示当前时间
在views.py中定义获取时间的函数,并在HTML中替换占位符。
5.3 示例:传递字典到页面
使用Jinja2模板引擎渲染HTML,支持后端代码语法操作数据。
- Jinja2模板引擎 =========== 6.1 操作字典
安装Jinja2并修改代码以支持字典操作:
from jinja2 import Template
def get_dict():
info = {"name": "avril", "age": 25}
with open("templates/get_dict.html", "r", encoding="utf-8") as f:
template_content = f.read()
template = Template(template_content)
return template.render(info=info)
6.2 数据库访问
连接数据库并渲染结果到HTML页面。
- 框架请求流程 ========= 7.1 流程图
省略图片描述。
7.2 关键术语解释
- 路由:路径配置。
- 视图函数:处理业务逻辑的函数。
- 路由层:
urls.py。 - 视图层:
views.py。 - 模板层:
templates文件夹。 - 静态资源层:
static文件夹。
- Python主流Web框架 ================
- Django
- Flask
- FastAPI
- Pyramid
- Tornado
- Sanic
- Aiohttp