本文全面解析Django REST Framework核心机制,涵盖请求处理、视图演进、路由配置等高级用法,助你彻底掌握API开发精髓!
目录
一、DRF请求与响应机制
1.1 Request对象解析
核心属性解析:
1.2 Response对象构建
1.3 HTTP状态码常量
二、DRF视图演进之路
2.1 基础视图类(APIView)
2.2 通用视图类(GenericAPIView)
2.3 五大Mixin扩展类
2.4 九大视图子类
九大视图子类全览:
三、视图集(ViewSet)与路由
3.1 视图集核心优势
3.2 视图集类型
1. ModelViewSet(全功能)
2. ReadOnlyModelViewSet(只读)
3. 自定义ViewSet
3.3 路由配置
1. 手动配置路由
2. 使用路由器自动生成
四、高级技巧:自定义Action
五、序列化器选择策略
何时使用Serializer vs ModelSerializer
六、路由系统深度解析
1. SimpleRouter vs DefaultRouter
2. 路由注册高级用法
3. 自定义路由URL
DRF扩展了Django的HttpRequest,提供更强大的请求处理能力:
# 视图类必须继承APIView
from rest_framework.views import APIView
from rest_framework.response import Response
class UserAPIView(APIView):
def get(self, request):
# 1. 获取查询参数
print(request.query_params)
#
# 2. 获取请求体数据(自动解析JSON/表单)
print(request.data)
# {'name': '灰太狼', 'age': 20}
# 3. 访问原生HttpRequest
print(request._request.META.get('Accept'))
return Response("OK")
.data
:包含解析后的请求体数据,支持JSON/表单格式
.query_params
:替代Django的request.GET,获取查询字符串
.FILES
:上传文件列表
.request
:访问底层Django请求对象
DRF的Response类支持内容协商,自动根据Accept头转换数据格式:
def post(self, request):
# 构造响应(自动处理内容协商)
return Response(
data={"status": "created"}, # Python原生数据类型
status=status.HTTP_201_CREATED, # 使用状态码常量
headers={"X-Custom-Header": "value"}
)
配置默认渲染器:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
DRF提供完整的状态码常量,提高代码可读性:
from rest_framework import status
# 常用状态码
HTTP_200_OK # 成功
HTTP_201_CREATED # 资源创建成功
HTTP_204_NO_CONTENT # 无内容(删除成功)
HTTP_400_BAD_REQUEST # 客户端错误
HTTP_404_NOT_FOUND # 资源不存在
HTTP_500_INTERNAL_SERVER_ERROR # 服务器错误
APIView是DRF所有视图的基类,扩展功能:
使用DRF的Request/Response对象
异常自动处理
增加认证/权限/限流机制
class StudentAPIView(APIView):
def get(self, request):
students = Student.objects.all()
serializer = StudentSerializer(students, many=True)
return Response(serializer.data)
核心优势:
声明queryset
和serializer_class
提供通用方法:get_queryset()
, get_object()
, get_serializer()
class StudentGenericAPIView(GenericAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get(self, request):
queryset = self.get_queryset() # 获取查询集
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
实现CRUD操作的复用:
Mixin类 | 方法 | 功能 |
---|---|---|
ListModelMixin | list() | 获取资源列表 |
CreateModelMixin | create() | 创建资源 |
RetrieveModelMixin | retrieve() | 获取单个资源 |
UpdateModelMixin | update() | 更新资源 |
DestroyModelMixin | destroy() | 删除资源 |
使用示例:
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class StudentMixinView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get(self, request): # 映射到list方法
return self.list(request)
def post(self, request): # 映射到create方法
return self.create(request)
进一步简化代码的终极方案:
# 列表+创建视图
from rest_framework.generics import ListCreateAPIView
class StudentLCView(ListCreateAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
# 检索+更新+删除视图
from rest_framework.generics import RetrieveUpdateDestroyAPIView
class StudentRUDView(RetrieveUpdateDestroyAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
CreateAPIView
- 仅创建
ListAPIView
- 仅列表
RetrieveAPIView
- 仅检索
DestroyAPIView
- 仅删除
UpdateAPIView
- 仅更新
ListCreateAPIView
- 列表+创建
RetrieveUpdateAPIView
- 检索+更新
RetrieveDestroyAPIView
- 检索+删除
RetrieveUpdateDestroyAPIView
- 检索+更新+删除
整合操作:一个类实现所有CRUD操作
路由解耦:通过路由器自动生成URL配置
自定义Action:支持非标准操作
from rest_framework.viewsets import ModelViewSet
class StudentViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer
from rest_framework.viewsets import ReadOnlyModelViewSet
class StudentReadOnlyViewSet(ReadOnlyModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer
from rest_framework.viewsets import ViewSet
class CustomViewSet(ViewSet):
def list(self, request): ...
def create(self, request): ...
def custom_action(self, request): ...
# urls.py
urlpatterns = [
path('students/', StudentViewSet.as_view({
'get': 'list',
'post': 'create'
})),
path('students//', StudentViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'delete': 'destroy'
})),
]
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'students', StudentViewSet, basename='student')
urlpatterns = [
path('', include(router.urls)),
]
生成的路由:
列表:GET /students/
创建:POST /students/
详情:GET /students/{pk}/
更新:PUT /students/{pk}/
删除:DELETE /students/{pk}/
使用@action
装饰器扩展视图集功能:
from rest_framework.decorators import action
class StudentViewSet(ModelViewSet):
# ...
@action(detail=False, methods=['get'])
def newest(self, request):
"""获取最新学生"""
student = Student.objects.latest('id')
serializer = self.get_serializer(student)
return Response(serializer.data)
@action(detail=True, methods=['post'], url_path='activate')
def activate_student(self, request, pk=None):
"""激活学生账号"""
student = self.get_object()
student.is_active = True
student.save()
return Response({'status': 'activated'})
@action参数详解:
detail
:是否操作单个对象(True/False)
methods
:允许的HTTP方法列表
url_path
:自定义URL路径(默认使用方法名)
场景 | 选择 | 示例 |
---|---|---|
非数据库操作 | Serializer | 登录验证、文件上传 |
数据库模型操作 | ModelSerializer | 学生信息、课程信息 |
需要完全自定义字段 | Serializer | 跨模型聚合数据 |
快速实现模型CRUD | ModelSerializer | 博客文章管理 |
ModelSerializer示例:
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__' # 包含所有字段
extra_kwargs = {
'age': {
'max_value': 25,
'error_messages': {
'max_value': '年龄不能超过25岁!'
}
}
}
Serializer示例:
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField(write_only=True)
def validate(self, data):
# 自定义验证逻辑
user = authenticate(**data)
if not user:
raise serializers.ValidationError("认证失败")
return user
特性 | SimpleRouter | DefaultRouter |
---|---|---|
API根视图 | × | √ |
格式后缀 | × | √ (.json/.api) |
路由结构 | 简单 | 复杂 |
适用场景 | 简单API | 需要文档的API |
router = DefaultRouter()
# 注册视图集
router.register(r'students', StudentViewSet)
# 添加自定义路由
urlpatterns = [
path('admin/', admin.site.urls),
path('custom-view/', CustomView.as_view()),
]
# 合并路由
urlpatterns += router.urls
class CustomRouter(DefaultRouter):
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('statistics/', self.get_statistics_view()),
]
return custom_urls + urls
掌握DRF的这些核心概念和高级技巧,将帮助你构建出更健壮、更易维护的RESTful API。本文涵盖的内容只是DRF强大功能的冰山一角,建议结合官方文档继续深入学习!