跳转至

Django REST Framework — Django 的 RESTful API 构建工具包


一句话说明

DRF(Django REST Framework)给 Django 加上序列化器、视图集、路由器、权限系统,让你用极少代码就能构建完整的 RESTful API,是 Django 生态做 API 的标准选择。


安装与配置

# pip 安装
pip install djangorestframework        # 当前版本 3.15+
pip install django                     # Django 5.2 LTS

# 在 settings.py 注册
# INSTALLED_APPS = [..., 'rest_framework']
# settings.py 配置
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",  # Session 认证
        "rest_framework.authentication.BasicAuthentication",    # Basic 认证
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",           # 默认需要登录
    ],
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 20,                                            # 每页20条
}

核心用法

序列化器(Serializer)

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

class PatientSerializer(serializers.ModelSerializer):
    """患者模型序列化器(自动从 Model 生成)"""

    # 添加只读计算字段
    age_group = serializers.SerializerMethodField()

    class Meta:
        model   = Patient                        # 对应的 Django 模型
        fields  = ["id", "name", "age", "diagnosis", "age_group", "created_at"]
        read_only_fields = ["id", "created_at"]  # 只读字段(不接受用户修改)

    def get_age_group(self, obj) -> str:
        """计算年龄段"""
        return "老年" if obj.age >= 60 else "中青年"

    def validate_age(self, value: int) -> int:
        """字段级验证"""
        if not 0 <= value <= 150:
            raise serializers.ValidationError("年龄必须在 0-150 之间")
        return value

视图集(ViewSet)

# views.py
from rest_framework import viewsets, permissions, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Patient
from .serializers import PatientSerializer

class PatientViewSet(viewsets.ModelViewSet):
    """患者 CRUD 接口(自动提供 list/create/retrieve/update/destroy)"""
    queryset         = Patient.objects.all().order_by("-created_at")  # 默认查询集
    serializer_class = PatientSerializer
    permission_classes = [permissions.IsAuthenticated]    # 需要登录

    # 支持过滤和搜索
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields   = ["name", "diagnosis"]               # 搜索字段
    ordering_fields = ["age", "created_at"]               # 可排序字段

    def get_queryset(self):
        """根据查询参数动态过滤"""
        qs = super().get_queryset()
        group = self.request.query_params.get("group")    # ?group=T2D
        if group:
            qs = qs.filter(diagnosis=group)
        return qs

    # 自定义动作(额外路由)
    @action(detail=False, methods=["GET"], url_path="stats")
    def statistics(self, request):
        """GET /api/patients/stats/ — 统计信息"""
        from django.db.models import Avg, Count
        stats = Patient.objects.aggregate(
            total=Count("id"),
            avg_age=Avg("age"),
        )
        return Response(stats)

路由注册

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

router = DefaultRouter()
router.register(r"patients", PatientViewSet, basename="patient")
# 自动生成:GET/POST /patients/, GET/PUT/DELETE /patients/{id}/
# 额外:GET /patients/stats/(自定义 action)

urlpatterns = router.urls

实战案例

带 Token 认证的 API

# settings.py 添加 Token 认证
# pip install djangorestframework
# python manage.py migrate  (生成 authtoken 表)

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.TokenAuthentication",  # Token 认证
    ],
}
INSTALLED_APPS = [..., "rest_framework.authtoken"]

# views.py 登录获取 Token
from rest_framework.authtoken.views import obtain_auth_token
# urls.py 添加:path("api/login/", obtain_auth_token)

# 客户端使用:
# curl -H "Authorization: Token abc123..." http://localhost:8000/api/patients/

常见报错与解决

报错原因解决
401 Authentication credentials not provided未传 Token请求头加 Authorization: Token xxx
403 You do not have permission权限不足检查 permission_classes 设置
400 This field is required必填字段未传检查序列化器的 required 字段
ImproperlyConfigured忘记注册 appINSTALLED_APPS'rest_framework'

速查表

操作代码/说明
模型序列化器class S(ModelSerializer): class Meta: model=M
完整 CRUD 视图集class V(ModelViewSet): queryset=..., serializer_class=...
注册路由router.register("path", ViewSet)
自定义动作@action(detail=False, methods=["GET"])
查询参数过滤request.query_params.get("key")
字段验证def validate_field(self, value): ...
Token 认证TokenAuthentication + obtain_auth_token
搜索过滤filter_backends=[SearchFilter], search_fields=["name"]