1. 为什么说这是最好的Python工作流?
在Python后端开发领域,FastAPI和Django的组合正在成为越来越多资深开发者的首选方案。我经历过从纯Django到Flask+SQLAlchemy,再到现在的FastAPI+Django ORM的技术栈演变,实测这套组合在开发效率、运行性能和长期维护性上达到了最佳平衡点。
这个工作流的核心优势在于:用FastAPI处理高并发接口和微服务,同时保留Django强大的ORM和Admin后台。就像给跑车装上航天级导航系统——FastAPI的异步特性(基于Starlette和Pydantic)让接口响应速度轻松突破万级QPS,而Django ORM提供的数据操作能力几乎覆盖所有业务场景。
关键数据:在相同硬件条件下,FastAPI的请求处理速度比传统Django View快3-5倍,而配合Django ORM后,数据库操作代码量比纯SQLAlchemy减少40%
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境搭建与项目初始化
2.1 创建虚拟环境
推荐使用Python 3.9+版本,这是目前最稳定的Django和FastAPI兼容版本。避免使用最新Python 3.12,某些Django插件可能尚未适配。
bash复制python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate.bat # Windows
2.2 依赖安装策略
不要直接pip install django fastapi,精确控制版本能避免后期兼容性问题:
bash复制pip install django==4.2.3 fastapi==0.95.2 "uvicorn[standard]" django-cors-headers
特别说明版本选择逻辑:
- Django 4.2 LTS:长期支持版本,维护到2026年
- FastAPI 0.95.2:当前稳定版,Pydantic v2兼容
- uvicorn带standard扩展:支持websocket和watch模式
3. Django作为数据引擎的配置技巧
3.1 精简版Django配置
在settings.py中只保留核心配置:
python复制INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes', # ORM必需
'django.contrib.sessions',
'your_app'
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
}
}
避坑提示:务必移除
django.middleware.csrf.CsrfViewMiddleware,否则会导致FastAPI接口403错误。安全防护应在前端或API网关层实现。
3.2 模型设计最佳实践
在models.py中使用Django ORM的全部能力:
python复制from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
mobile = models.CharField(max_length=15, unique=True)
class Product(models.Model):
STATUS_CHOICES = [
('draft', '草稿'),
('published', '已发布'),
('archived', '归档')
]
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=10, decimal_places=2)
status = models.CharField(max_length=20, choices=STATUS_CHOICES)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
indexes = [
models.Index(fields=['status', 'created_at']),
]
4. FastAPI核心服务搭建
4.1 主应用架构设计
创建main.py作为入口文件:
python复制from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from django.conf import settings
import django
django.setup() # 初始化Django环境
app = FastAPI(title="Hybrid API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def root():
return {"message": "API is running"}
4.2 数据库操作层封装
创建db_utils.py实现Django ORM的异步封装:
python复制from asgiref.sync import sync_to_async
from your_app.models import Product
@sync_to_async
def create_product(**data):
return Product.objects.create(**data)
@sync_to_async
def list_products(status=None):
queryset = Product.objects.all()
if status:
queryset = queryset.filter(status=status)
return list(queryset.values())
5. 实战:用户认证系统实现
5.1 JWT认证集成
安装额外依赖:
bash复制pip install python-jose[cryptography] passlib[bcrypt]
创建auth.py:
python复制from datetime import datetime, timedelta
from jose import jwt
from passlib.context import CryptContext
from django.conf import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
SECRET_KEY = "your-secret-key" # 生产环境应从环境变量读取
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password):
return pwd_context.hash(password)
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
5.2 用户注册/登录接口
在main.py中添加路由:
python复制from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/register")
async def register(username: str, password: str, mobile: str):
from your_app.models import User
if User.objects.filter(username=username).exists():
raise HTTPException(status_code=400, detail="Username already exists")
hashed_password = get_password_hash(password)
user = User.objects.create(
username=username,
password=hashed_password,
mobile=mobile
)
return {"id": user.id}
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = User.objects.filter(username=form_data.username).first()
if not user or not verify_password(form_data.password, user.password):
raise HTTPException(status_code=400, detail="Incorrect credentials")
access_token = create_access_token(data={"sub": user.username})
return {"access_token": access_token, "token_type": "bearer"}
6. 性能优化关键策略
6.1 异步查询优化
使用asgiref.sync.sync_to_async包装Django ORM查询时,注意:
python复制# 错误示范:N+1查询问题依然存在
products = await list_products()
for p in products:
p['creator'] = await get_user(p['creator_id']) # 每次循环都查数据库
# 正确做法:一次性预加载
@sync_to_async
def list_products_with_creator():
return list(Product.objects.select_related('creator').values())
6.2 缓存集成方案
安装Redis支持:
bash复制pip install redis hiredis aioredis
配置缓存装饰器:
python复制from fastapi import Request
from functools import wraps
import aioredis
redis = aioredis.from_url("redis://localhost")
def cache_response(ttl: int = 60):
def decorator(func):
@wraps(func)
async def wrapper(request: Request, *args, **kwargs):
cache_key = f"{request.url.path}?{request.url.query}"
cached = await redis.get(cache_key)
if cached:
return cached
result = await func(request, *args, **kwargs)
await redis.setex(cache_key, ttl, result)
return result
return wrapper
return decorator
@app.get("/products")
@cache_response(ttl=120)
async def product_list():
return await list_products()
7. 生产环境部署要点
7.1 使用Gunicorn+Uvicorn
创建gunicorn_conf.py:
python复制import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "uvicorn.workers.UvicornWorker"
bind = "0.0.0.0:8000"
timeout = 120
keepalive = 5
启动命令:
bash复制gunicorn -c gunicorn_conf.py main:app
7.2 数据库连接池配置
在Django的settings.py中添加:
python复制DATABASES['default']['CONN_MAX_AGE'] = 600 # 10分钟连接池
DATABASES['default']['OPTIONS'] = {
'connect_timeout': 5,
'application_name': 'your_app'
}
8. 开发调试技巧
8.1 热重载配置
使用uvicorn开发模式启动:
bash复制uvicorn main:app --reload --reload-include *.py --reload-exclude venv/*
8.2 接口文档自动生成
FastAPI默认提供:
- Swagger UI:
/docs - ReDoc:
/redoc
自定义文档说明:
python复制@app.post("/products/",
response_model=ProductOut,
summary="创建新产品",
description="需要管理员权限",
tags=["产品管理"])
async def create_product(item: ProductIn):
...
9. 项目结构建议
推荐的组织方式:
code复制project/
├── core/ # 公共组件
│ ├── config.py # 配置管理
│ ├── exceptions.py # 自定义异常
│ └── security.py # 安全相关
├── apps/
│ ├── auth/ # 认证模块
│ │ ├── routers.py
│ │ └── schemas.py
│ └── products/ # 产品模块
│ ├── models.py
│ └── services.py
├── db/ # 数据库相关
│ ├── session.py
│ └── utils.py
├── static/ # 静态文件
├── tests/ # 测试代码
├── main.py # 应用入口
└── requirements.txt
10. 常见问题解决方案
10.1 Django静态文件冲突
在settings.py中添加:
python复制STATIC_URL = '/django_static/' # 区别于FastAPI的/static
10.2 时区处理统一
强制所有时间使用UTC:
python复制TIME_ZONE = 'UTC'
USE_TZ = True
在FastAPI中转换:
python复制from datetime import datetime
def now():
return datetime.utcnow()
10.3 事务管理
使用Django的原子操作:
python复制from django.db import transaction
@sync_to_async
@transaction.atomic
def create_order(items):
order = Order.objects.create(...)
for item in items:
OrderItem.objects.create(order=order, ...)
return order
这套工作流经过多个中大型项目验证,在保持Django强大生态的同时,通过FastAPI获得了现代Python的异步能力。实际开发中,建议将业务逻辑尽可能放在Django模型层,FastAPI主要作为接口层,这样既能享受Django ORM的便利,又能获得FastAPI的性能优势。
