跳转至

Django REST Framework

一句话概述:Django REST Framework(DRF)是 Django 的 API 扩展,提供序列化、认证、权限、分页等开箱即用的功能,适合快速构建功能完善的 RESTful API。

核心知识点

概念白话解释
Serializer序列化器 = 把数据库对象转成 JSON(以及反过来)
ViewSet视图集 = 一个类处理一个资源的所有 CRUD 操作
Router路由器 = 自动为 ViewSet 生成 URL
Permission权限 = 控制谁能访问哪些 API
Authentication认证 = 验证用户身份
Pagination分页 = 大量数据分页返回
Filter过滤 = 按条件筛选数据
Throttle限流 = 限制 API 调用频率

安装配置

pip install djangorestframework  # 安装 DRF
pip install django-filter  # 安装过滤器支持
# settings.py
INSTALLED_APPS = [
    ...
    'rest_framework',  # 注册 DRF
    'django_filters',  # 注册过滤器
]

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20,  # 默认每页20条
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',  # Token 认证
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',  # 默认需要登录
    ],
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',  # 过滤
        'rest_framework.filters.SearchFilter',  # 搜索
        'rest_framework.filters.OrderingFilter',  # 排序
    ],
}

基本使用

1. Model + Serializer + ViewSet + Router

# models.py
from django.db import models

class Sample(models.Model):
    name = models.CharField(max_length=100)  # 样本名
    species = models.CharField(max_length=100)  # 物种
    sequencing_type = models.CharField(max_length=50)  # 测序类型
    created_at = models.DateTimeField(auto_now_add=True)  # 创建时间

# serializers.py
from rest_framework import serializers
from .models import Sample

class SampleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sample  # 关联的模型
        fields = '__all__'  # 序列化所有字段
        read_only_fields = ['created_at']  # 只读字段

# views.py
from rest_framework import viewsets
from .models import Sample
from .serializers import SampleSerializer

class SampleViewSet(viewsets.ModelViewSet):
    """样本的 CRUD API(自动包含 list/create/retrieve/update/destroy)"""
    queryset = Sample.objects.all()  # 查询集
    serializer_class = SampleSerializer  # 序列化器
    filterset_fields = ['species', 'sequencing_type']  # 可过滤的字段
    search_fields = ['name']  # 可搜索的字段
    ordering_fields = ['created_at', 'name']  # 可排序的字段

# urls.py
from rest_framework.routers import DefaultRouter
from .views import SampleViewSet

router = DefaultRouter()
router.register('samples', SampleViewSet)  # 注册路由

urlpatterns = router.urls
# 自动生成:GET/POST /samples/, GET/PUT/DELETE /samples/{id}/

2. 自定义序列化验证

class SampleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sample
        fields = '__all__'

    def validate_name(self, value):
        """验证样本名格式"""
        if not value.startswith("S"):
            raise serializers.ValidationError("样本名必须以 S 开头")
        return value

    def validate(self, data):
        """跨字段验证"""
        if data.get('sequencing_type') == 'WGS' and not data.get('species'):
            raise serializers.ValidationError("WGS 测序必须指定物种")
        return data

高级用法

1. 自定义权限

from rest_framework.permissions import BasePermission

class IsOwnerOrReadOnly(BasePermission):
    """只有创建者可以修改,其他人只读"""
    def has_object_permission(self, request, view, obj):
        if request.method in ('GET', 'HEAD', 'OPTIONS'):
            return True  # 读取操作允许所有人
        return obj.owner == request.user  # 写操作只允许所有者

class SampleViewSet(viewsets.ModelViewSet):
    permission_classes = [IsOwnerOrReadOnly]  # 使用自定义权限

2. 嵌套序列化器

class AnalysisSerializer(serializers.ModelSerializer):
    sample = SampleSerializer(read_only=True)  # 嵌套返回样本详情
    sample_id = serializers.PrimaryKeyRelatedField(
        queryset=Sample.objects.all(), source='sample', write_only=True
    )  # 创建时只需传 sample_id

    class Meta:
        model = Analysis
        fields = ['id', 'sample', 'sample_id', 'result', 'created_at']

3. 自定义动作

from rest_framework.decorators import action
from rest_framework.response import Response

class SampleViewSet(viewsets.ModelViewSet):
    @action(detail=True, methods=['post'])  # /samples/{id}/run_analysis/
    def run_analysis(self, request, pk=None):
        """运行分析(自定义动作)"""
        sample = self.get_object()
        # 执行分析逻辑...
        return Response({"status": "analysis started"})

    @action(detail=False, methods=['get'])  # /samples/statistics/
    def statistics(self, request):
        """统计信息"""
        total = self.get_queryset().count()
        return Response({"total_samples": total})

常见报错

报错信息原因解决方法
401 Unauthorized未提供认证信息请求头加 Authorization: Token xxx
400 Bad Request数据验证失败查看响应体中的具体错误信息
403 Forbidden权限不足检查 permission_classes
Field is required缺少必填字段检查请求体

速查表

# === ViewSet 类型 ===
ModelViewSet        # 完整 CRUD
ReadOnlyModelViewSet  # 只读(list + retrieve)
GenericViewSet      # 基础视图集(自己加 mixin)

# === Mixin ===
CreateModelMixin    # 创建
ListModelMixin      # 列表
RetrieveModelMixin  # 详情
UpdateModelMixin    # 更新
DestroyModelMixin   # 删除

# === 认证类 ===
TokenAuthentication      # Token 认证
SessionAuthentication    # Session 认证
BasicAuthentication      # Basic 认证(测试用)

# === 权限类 ===
AllowAny                 # 允许所有
IsAuthenticated          # 需登录
IsAdminUser              # 需管理员
IsAuthenticatedOrReadOnly  # 登录可写,匿名只读

# === 过滤/搜索/排序 ===
filterset_fields = ['field']       # 精确过滤
search_fields = ['field']          # 模糊搜索(?search=xxx)
ordering_fields = ['field']        # 排序(?ordering=-field)

参考:DRF 文档 | 更新于 2026 年