Python Web框架设计模式
理解Web框架设计模式有助于选择合适框架和编写高质量Web应用。
MVC设计模式
MVC核心概念
Python
MVC = Model + View + Controller
Model:数据模型,业务逻辑和数据访问
View:视图层,展示数据给用户
Controller:控制器,处理用户请求,协调Model和View
请求流程:
用户请求 → Controller → Model → View → 响应
MVC在Python框架
Python
# 传统MVC实现示例
# Model
class UserModel:
def __init__(self, db):
self.db = db
def get_all(self):
return self.db.query('SELECT * FROM users')
def create(self, name, email):
return self.db.execute('INSERT INTO users VALUES (?, ?)', name, email)
# View
class UserView:
def render_list(self, users):
return '<ul>' + ''.join(f'<li>{u.name}</li>' for u in users) + '</ul>'
def render_detail(self, user):
return f'<h1>{user.name}</h1><p>{user.email}</p>'
# Controller
class UserController:
def __init__(self, model, view):
self.model = model
self.view = view
def list(self):
users = self.model.get_all()
return self.view.render_list(users)
def create(self, name, email):
user = self.model.create(name, email)
return self.view.render_detail(user)
MTV设计模式
Django MTV架构
Python
MTV = Model + Template + View(Django术语)
Model:数据模型,ORM映射
Template:模板,HTML渲染
View:视图函数,处理请求逻辑
Django MTV对应传统MVC:
Model → Model
Template → View
View → Controller
Django MTV实践
Python
# Django MTV示例
# Model(models.py)
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
created_at = models.DateTimeField(auto_now_add=True)
# View(views.py)
from django.shortcuts import render, get_object_or_404
def user_list(request):
# Controller逻辑:处理请求
users = User.objects.all()
# Template渲染:返回视图
return render(request, 'users/list.html', {'users': users})
def user_detail(request, pk):
user = get_object_or_404(User, pk=pk)
return render(request, 'users/detail.html', {'user': user})
# Template(templates/users/list.html)
<ul>
{% for user in users %}
<li>{{ user.name }} - {{ user.email }}</li>
{% endfor %}
</ul>
中间件模式
中间件概念
Python
# 中间件:请求/响应处理链
请求流程:
Request → Middleware1 → Middleware2 → ... → View → Response
Response → MiddlewareN → ... → Middleware2 → Middleware1 → Client
# 中间件功能:
# 1. 请求预处理(认证、日志)
# 2. 响应后处理(压缩、添加头)
# 3. 异常处理
# 4. 请求拦截
Django中间件
Python
# Django中间件实现
class CustomMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求预处理
request.custom_data = 'preprocessed'
response = self.get_response(request)
# 响应后处理
response['X-Custom-Header'] = 'value'
return response
def process_view(self, request, view_func, view_args, view_kwargs):
# 视图调用前处理
pass
def process_exception(self, request, exception):
# 异常处理
pass
# settings.py配置
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'myapp.middleware.CustomMiddleware',
]
Flask中间件
Python
# Flask使用before_request/after_request
from flask import Flask, request, g
app = Flask(__name__)
@app.before_request
def before_request():
# 请求预处理
g.user = get_current_user()
g.start_time = time.time()
@app.after_request
def after_request(response):
# 响应后处理
elapsed = time.time() - g.start_time
response.headers['X-Response-Time'] = str(elapsed)
return response
@app.teardown_request
def teardown_request(exception):
# 请求结束清理
pass
FastAPI中间件
Python
from fastapi import FastAPI, Request
from fastapi.middleware import Middleware
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS中间件
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_methods=['*'],
allow_headers=['*']
)
# 自定义中间件
@app.middleware('http')
async def custom_middleware(request: Request, call_next):
# 请求预处理
start_time = time.time()
response = await call_next(request)
# 响应后处理
response.headers['X-Process-Time'] = str(time.time() - start_time)
return response
路由设计模式
Django路由
Python
# Django URL配置
# urls.py
from django.urls import path, include
urlpatterns = [
path('users/', include('users.urls')),
path('products/', include('products.urls')),
path('admin/', admin.site.urls),
]
# users/urls.py
urlpatterns = [
path('', views.user_list, name='user-list'),
path('<int:pk>/', views.user_detail, name='user-detail'),
path('create/', views.user_create, name='user-create'),
]
# 路由特点:
# 1. 集中式URL配置
# 2. 支持include嵌套
# 3. 支持命名路由
# 4. 支持正则匹配
Flask路由
Python
# Flask路由装饰器
from flask import Flask
app = Flask(__name__)
@app.route('/users')
def user_list():
pass
@app.route('/users/<int:user_id>')
def user_detail(user_id):
pass
@app.route('/users', methods=['POST'])
def create_user():
pass
# 路由特点:
# 1. 装饰器定义路由
# 2. 与视图函数绑定
# 3. 支持HTTP方法限定
# 4. 支持URL参数类型转换
FastAPI路由
Python
from fastapi import FastAPI
app = FastAPI()
@app.get('/users')
async def get_users():
pass
@app.get('/users/{user_id}')
async def get_user(user_id: int): # 自动类型转换
pass
@app.post('/users')
async def create_user(user: UserCreate):
pass
# 路由特点:
# 1. 装饰器指定HTTP方法
# 2. 类型注解自动验证
# 3. 自动生成OpenAPI文档
# 4. 异步支持
请求处理模式
WSGI协议
Python
# WSGI:Python Web服务器网关接口
def application(environ, start_response):
"
WSGI应用入口
environ: 请求环境字典
start_response: 响应启动函数
"
# 解析请求
method = environ['REQUEST_METHOD']
path = environ['PATH_INFO']
# 处理请求
if path == '/hello':
body = b'Hello World'
else:
body = b'Not Found'
# 发送响应
start_response('200 OK', [('Content-Type', 'text/plain')])
return [body]
# Flask/Django底层都使用WSGI
ASGI协议
Python
# ASGI:异步服务器网关接口(支持WebSocket)
async def application(scope, receive, send):
"
ASGI应用入口
scope: 连接信息
receive: 接收消息
send: 发送消息
"
if scope['type'] == 'http':
# HTTP请求处理
await send({
'type': 'http.response.start',
'status': 200,
'headers': [(b'content-type', b'text/plain')]
})
await send({
'type': 'http.response.body',
'body': b'Hello ASGI'
})
elif scope['type'] == 'websocket':
# WebSocket处理
pass
# FastAPI底层使用ASGI
模板渲染模式
Django模板
text
# Django模板引擎
# 视图返回模板
def user_list(request):
users = User.objects.all()
return render(request, 'users/list.html', {'users': users})
# 模板语法
# users/list.html
<h1>User List</h1>
<ul>
{% for user in users %}
<li>
{{ user.name }}
{% if user.is_admin %}
<span class="badge">Admin</span>
{% endif %}
</li>
{% empty %}
<li>No users</li>
{% endfor %}
</ul>
# 模板继承
# base.html
{% block content %}{% endblock %}
# list.html
{% extends 'base.html' %}
{% block content %}
...
{% endblock %}
Jinja2模板
text
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('user.html')
html = template.render(user={'name': 'Alice', 'email': 'a@b.com'})
# Jinja2语法(类似Django)
{{ user.name }}
{% if user.is_admin %}Admin{% endif %}
{% for user in users %}{{ user.name }}{% endfor %}
# Flask默认使用Jinja2
@app.route('/user/<int:id>')
def user(id):
user = get_user(id)
return render_template('user.html', user=user)
框架对比
| 特性 | Django | Flask | FastAPI |
|---|---|---|---|
| 架构 | MTV全栈 | 微框架轻量 | 异步微框架 |
| ORM | 内置Django ORM | 无(可选) | 无(可选) |
| 模板 | 内置 | Jinja2 | 无 |
| 异步 | 支持(Django 4+) | 不支持 | 原生支持 |
| 类型验证 | 无 | 无 | 自动验证 |
| API文档 | 无 | 无 | 自动生成 |
| 中间件 | 类中间件 | before/after | @app.middleware |
注意:选择框架要看项目需求,Django适合全栈应用,Flask灵活扩展,FastAPI适合API服务。
要点总结
- MVC/MTV:模型-视图-控制器分层,职责分离清晰
- 中间件:请求/响应处理链,可添加认证、日志、异常处理
- 路由模式:URL映射视图函数,支持参数提取和类型转换
- WSGI/ASGI:WSGI同步HTTP,ASGI支持异步和WebSocket
- 模板渲染:Django内置模板,Flask用Jinja2,FastAPI无内置模板
存放路径:articles/PYTHON/专家/生态与工具链/Web框架设计模式.md
📝 发现内容有误?点击此处直接编辑