文章目录
震惊!!! 上周隔壁组花两周写的接口,我用DRF(Django REST framework)三小时全搞定!老板看我的眼神像看外星人👽…(其实秘密武器就藏在
ViewSets里!)
01 为什么你的API写得像老太太裹脚布?
还记得上次手写用户管理接口的噩梦吗?
# 传统Django视图写法(血压警告⚠️)
def user_list(request):
if request.method == 'GET':
users = User.objects.all()
data = [{"id": u.id, "name": u.name} for u in users] # 手动序列化?No!
return JsonResponse(data, safe=False)
elif request.method == 'POST':
try:
data = json.loads(request.body) # 手动解析JSON?Stop!!!
User.objects.create(name=data['name'])
return HttpResponse(status=201)
except:
return HttpResponse(status=400)
(看到没?光是增删改查就要写200行!还容易漏权限验证!)
02 DRF魔法时刻:三行代码生成完整API❗
感受下什么是降维打击:
# DRF终极奥义(扶好眼镜👓)
from rest_framework import viewsets, serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__" # 自动序列化所有字段!
class UserViewSet(viewsets.ModelViewSet): # 核心魔法在这里!
queryset = User.objects.all()
serializer_class = UserSerializer
发生了什么???
- ✅ GET /users/ → 获取用户列表
- ✅ POST /users/ → 创建用户
- ✅ GET /users/1/ → 获取单个用户
- ✅ PUT /users/1/ → 修改用户
- ✅ DELETE /users/1/ → 删除用户
(别数了!上面真的只有3行有效代码!DRF自动处理了HTTP方法、序列化、路由映射…)
03 灵魂组件解剖:DRF如何把Django变成API怪兽🚀
▶ 序列化器(Serializers):数据变形金刚
你以为只是转JSON?太天真!
# 高级玩法:动态字段控制(客户端直呼内行!)
class UserSerializer(serializers.ModelSerializer):
is_admin = serializers.SerializerMethodField() # 自定义字段!
class Meta:
model = User
fields = ["id", "name", "email", "is_admin"]
def get_is_admin(self, obj):
return obj.groups.filter(name="Admin").exists() # 实时计算字段!
(重要技巧💡)用source参数直接操作模型关系:
created_at = serializers.DateTimeField(source="profile.create_time")
▶ 视图集(ViewSets):路由生成器
路由配置简化到窒息:
# urls.py(见证奇迹)
from rest_framework.routers import DefaultRouter
from .views import UserViewSet
router = DefaultRouter()
router.register(r'users', UserViewSet) # 自动生成所有路由!
urlpatterns = router.urls # 一行导入所有URL!
输出路由表:
- /users/ →
UserViewSet.as_view({'get': 'list', 'post': 'create'}) - /users/{pk}/ →
UserViewSet.as_view({'get': 'retrieve', 'put': 'update'})
▶ 权限控制:API守卫队长
用装饰器实现权限分层(超实用!!!):
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
@permission_classes([IsAuthenticated]) # 普通用户权限
def list(self, request):
...
@permission_classes([IsAdminUser]) # 管理员专属
def destroy(self, request, pk=None):
...
(真实踩坑警告🚨)生产环境必加限流:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'anon': '100/hour', # 匿名用户限制
'user': '1000/minute' # 登录用户限制
}
}
04 杀手锏功能:自动API文档(前端跪谢版)
启用Swagger支持(前端再也不用追着你要文档了!):
pip install drf-yasg # 文档神器
# urls.py 配置
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(title="我的API", default_version='v1'),
public=True,
)
urlpatterns += [
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0)),
]
访问/swagger/直接获得:
- 实时交互式测试界面
- 参数自动说明
- 身份认证集成(JWT/OAuth2一键配置)
05 真实项目避坑指南(血泪经验)
🔥 坑1:N+1查询问题(性能刺客)
错误写法:
queryset = User.objects.all() # 获取用户列表时会触发N次查询取关联数据!
DRF解决方案:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.select_related('profile').prefetch_related('groups')
# 一次SQL搞定所有关联数据!
🔥 坑2:无限递归序列化
当两个模型互相引用时:
class DepartmentSerializer(serializers.ModelSerializer):
employees = EmployeeSerializer(many=True) # 死循环警告!
class EmployeeSerializer(serializers.ModelSerializer):
department = DepartmentSerializer() # 互相调用 → StackOverflow!
正确方案:用StringRelatedField切断循环
department = serializers.StringRelatedField() # 只显示部门名称字符串
06 谁说DRF不能玩骚操作?
▶ 动态序列化字段(按需加载)
URL传参控制返回字段:/users/?fields=id,name,email
class UserViewSet(viewsets.ModelViewSet):
def get_serializer_context(self):
context = super().get_serializer_context()
context['fields'] = self.request.query_params.get('fields', '').split(',')
return context
class UserSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
fields = kwargs.pop('context', {}).get('fields', [])
super().__init__(*args, **kwargs)
if fields: # 动态过滤字段!
allowed = set(fields)
existing = set(self.fields)
for field in existing - allowed:
self.fields.pop(field)
▶ 批量操作(毁灭性能利器,慎用!)
class BatchUserView(APIView):
def post(self, request):
serializer = UserSerializer(data=request.data, many=True) # 关键参数!
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
07 前方高能:DRF不是银弹!
这些场景慎用DRF:
- ❗ 超简单API → 直接用
JsonResponse更轻量 - ❗ 需要GraphQL → 看
graphene-django - ❗ 实时通信需求 → 上
Django Channels
(真实案例翻车🚑)我们曾在物联网项目用DRF处理10万+/秒的传感器数据 → 直接崩了!后来换成了FastAPI + Redis流处理。
08 最后送你一把屠龙刀🗡️
DRF最佳学习路径:
1️⃣ 官方教程(务必动手敲!) → DRF官方文档
2️⃣ 玩透序列化器(SerializerMethodField是神器)
3️⃣ 掌握权限控制(permission_classes比中间件灵活)
4️⃣ 征服视图集(ModelViewSet能解决80%需求)
老板昨天问我:“你写API这么快是不是在摸鱼?”
我邪魅一笑:“不,我只是把时间花在ViewSet而不是View上!” 💥
(偷偷说)DRF就像乐高积木——入门简单,但想搭出埃菲尔铁塔?得先被零件扎几次手!现在就去动手试试看吧!

被折叠的 条评论
为什么被折叠?



