DRF终极指南:从请求响应到视图集路由的深度解析

        本文全面解析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请求与响应机制

1.1 Request对象解析

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请求对象

1.2 Response对象构建

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',
    ]
}

1.3 HTTP状态码常量

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  # 服务器错误

二、DRF视图演进之路

2.1 基础视图类(APIView)

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)

2.2 通用视图类(GenericAPIView)

核心优势

  • 声明querysetserializer_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)

2.3 五大Mixin扩展类

实现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)

2.4 九大视图子类

进一步简化代码的终极方案:

# 列表+创建视图
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

九大视图子类全览

  1. CreateAPIView - 仅创建

  2. ListAPIView - 仅列表

  3. RetrieveAPIView - 仅检索

  4. DestroyAPIView - 仅删除

  5. UpdateAPIView - 仅更新

  6. ListCreateAPIView - 列表+创建

  7. RetrieveUpdateAPIView - 检索+更新

  8. RetrieveDestroyAPIView - 检索+删除

  9. RetrieveUpdateDestroyAPIView - 检索+更新+删除

三、视图集(ViewSet)与路由

3.1 视图集核心优势

  1. 整合操作:一个类实现所有CRUD操作

  2. 路由解耦:通过路由器自动生成URL配置

  3. 自定义Action:支持非标准操作

3.2 视图集类型

1. ModelViewSet(全功能)

from rest_framework.viewsets import ModelViewSet

class StudentViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

2. ReadOnlyModelViewSet(只读)

from rest_framework.viewsets import ReadOnlyModelViewSet

class StudentReadOnlyViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

3. 自定义ViewSet

from rest_framework.viewsets import ViewSet

class CustomViewSet(ViewSet):
    def list(self, request): ...
    def create(self, request): ...
    def custom_action(self, request): ...

3.3 路由配置

1. 手动配置路由

# urls.py
urlpatterns = [
    path('students/', StudentViewSet.as_view({
        'get': 'list',
        'post': 'create'
    })),
    path('students//', StudentViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    })),
]

2. 使用路由器自动生成

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

使用@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 vs ModelSerializer
场景 选择 示例
非数据库操作 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

六、路由系统深度解析

1. SimpleRouter vs DefaultRouter

特性 SimpleRouter DefaultRouter
API根视图 ×
格式后缀 × √ (.json/.api)
路由结构 简单 复杂
适用场景 简单API 需要文档的API

2. 路由注册高级用法

router = DefaultRouter()

# 注册视图集
router.register(r'students', StudentViewSet)

# 添加自定义路由
urlpatterns = [
    path('admin/', admin.site.urls),
    path('custom-view/', CustomView.as_view()),
]

# 合并路由
urlpatterns += router.urls

3. 自定义路由URL

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强大功能的冰山一角,建议结合官方文档继续深入学习!

 

你可能感兴趣的:(python,开发语言)