Django Rest Framework (DRF) 核心知识体系梳理与深度讲解

文章目录

    • [一、DRF 核心架构:先搞懂"骨架"](#一、DRF 核心架构:先搞懂“骨架”)
      • [1. API 请求生命周期(核心脉络)](#1. API 请求生命周期(核心脉络))
      • [2. 核心设计原则](#2. 核心设计原则)
    • [二、DRF 核心组件(必掌握)](#二、DRF 核心组件(必掌握))
    • [三、DRF 进阶特性(提升效率)](#三、DRF 进阶特性(提升效率))
      • [1. 异常处理(Exception Handling)](#1. 异常处理(Exception Handling))
      • [2. 版本控制(Versioning)](#2. 版本控制(Versioning))
      • [3. 内容协商(Content Negotiation)](#3. 内容协商(Content Negotiation))
    • [四、DRF 最佳实践(避坑指南)](#四、DRF 最佳实践(避坑指南))
      • [1. 性能优化](#1. 性能优化)
      • [2. 代码组织](#2. 代码组织)
      • [3. 安全规范](#3. 安全规范)
      • [4. 测试](#4. 测试)
    • 五、核心总结

DRF 是 Django 生态中最主流的 RESTful API 开发框架,其核心设计理念是 在 Django 原生能力基础上,通过「组件化、可配置、可扩展」的方式,快速构建标准化、高可用的 API 。本文将从「核心架构→核心组件→进阶特性→最佳实践」四层,系统梳理 DRF 的知识体系,兼顾原理与实战。

一、DRF 核心架构:先搞懂"骨架"

DRF 的核心架构围绕「请求-响应生命周期」展开,所有组件都是为了解决生命周期中不同环节的问题。先明确一次 API 请求的完整流程,再拆解组件:

1. API 请求生命周期(核心脉络)

复制代码
客户端请求 → URL 路由匹配 → 视图(View/ViewSet)处理 → 数据序列化/校验 → 数据库交互 → 响应返回
          ↓          ↓           ↓               ↓              ↓
       路由组件    认证/权限/限流   视图核心逻辑    序列化组件     数据库适配

2. 核心设计原则

  • 继承扩展:所有核心组件(视图、序列化器、认证等)都基于"基类+扩展类"设计,保留 Django 原生逻辑,新增 API 能力;
  • 配置优先 :通过类属性/配置文件替代硬编码,比如 permission_classesserializer_class
  • 组件解耦:每个核心能力(认证、权限、序列化)都是独立组件,可自由组合/替换;
  • RESTful 规范:内置支持 RESTful 核心特性(资源路由、HTTP 方法映射、状态码标准化)。

二、DRF 核心组件(必掌握)

1. 序列化组件(Serializers):数据转换与校验的核心

(1)核心作用
  • 数据序列化 :将 Django 模型(Model)实例/查询集转换为 JSON/XML 等可传输格式(serializer.data);
  • 数据反序列化 :将客户端传入的原始数据(如 JSON)转换为 Python 字典,并完成数据校验(serializer.is_valid());
  • 数据保存 :校验通过后,通过 serializer.save() 完成数据库增/改操作。
(2)核心序列化器类型
序列化器类 适用场景 核心特点
Serializer 非模型数据(如登录请求) 手动定义所有字段,灵活度最高
ModelSerializer 模型数据(90%+场景) 自动映射模型字段,减少代码
ReadOnlyModelSerializer 仅只读接口(只查不改) 自动生成只读字段
(3)核心用法(ModelSerializer 示例)
python 复制代码
# serializers.py
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    # 自定义字段(非模型字段)
    author_name = serializers.CharField(source='author.username', read_only=True)
    
    class Meta:
        model = Book  # 关联模型
        fields = ['id', 'title', 'price', 'author', 'author_name']  # 要序列化的字段
        # exclude = ['is_deleted']  # 排除字段(二选一:fields/exclude)
        read_only_fields = ['id']  # 只读字段(客户端无法修改)
        extra_kwargs = {  # 字段级配置
            'price': {'min_value': 0, 'required': True},
            'title': {'max_length': 100}
        }
    
    # 自定义字段校验(单字段)
    def validate_title(self, value):
        if '非法' in value:
            raise serializers.ValidationError('标题包含非法内容')
        return value
    
    # 自定义全局校验(多字段)
    def validate(self, attrs):
        if attrs.get('price') > 1000 and attrs.get('title') == '测试':
            raise serializers.ValidationError('测试书籍价格不能超过1000')
        return attrs
    
    # 自定义保存逻辑(创建/更新)
    def create(self, validated_data):
        # 自动关联当前登录用户为作者
        validated_data['author'] = self.context['request'].user
        return super().create(validated_data)
(4)关键技巧
  • source:指定字段映射的模型属性(支持跨关联查询,如 author.username);
  • context:序列化器上下文(默认包含 request/view/format,可传递自定义数据);
  • many=True:序列化查询集(多个实例)时必须传;
  • partial=True:支持部分更新(PATCH 请求)。

2. 视图组件(Views/ViewSets):API 逻辑的载体

视图是 DRF 最核心的组件之一,进化路径已在前文详细讲解,这里梳理核心选型原则:

视图类型 核心能力 适用场景
APIView 基础API能力(解析、认证、响应) 非CRUD逻辑(如登录、支付、复杂业务)
GenericAPIView APIView + 通用查询/序列化 需自定义CRUD逻辑,复用查询/序列化
GenericAPIView + Mixins 通用视图 + CRUD混入逻辑 部分自定义的CRUD(如只需要列表+创建)
ModelViewSet 终极封装(全CRUD + 路由自动生成) 标准RESTful CRUD接口(优先选用)
ReadOnlyModelViewSet 仅只读CRUD(列表+详情) 只查不改的API(如商品列表、新闻详情)
核心扩展点(自定义视图逻辑)
  • get_queryset():自定义查询集(如过滤当前用户数据、动态条件过滤);

  • get_serializer_class():动态切换序列化器(如列表用简易序列化器,详情用完整序列化器);

  • perform_create()/perform_update()/perform_destroy():自定义数据保存/删除逻辑;

  • action 装饰器:自定义非标准动作(如批量删除、导出Excel):

    python 复制代码
    from rest_framework.decorators import action
    from rest_framework.response import Response
    
    class BookViewSet(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
    
        # 自定义动作:GET /books/export_excel/
        @action(detail=False, methods=['get'])  # detail=False → 列表级动作,True→详情级
        def export_excel(self, request):
            # 实现导出Excel逻辑
            return Response({'msg': '导出成功'})
        
        # 自定义动作:POST /books/{id}/change_status/
        @action(detail=True, methods=['post'])
        def change_status(self, request, pk=None):
            book = self.get_object()
            book.status = request.data.get('status')
            book.save()
            return Response(BookSerializer(book).data)

3. 路由组件(Routers):URL 与视图的映射

DRF 提供两种路由方式,适配不同视图类型:

(1)普通路由(适配 APIView/GenericAPIView)

和 Django 原生路由一致,手动映射 URL 到视图的 as_view() 方法:

python 复制代码
# urls.py
from django.urls import path
from .views import BookListView, BookDetailView

urlpatterns = [
    path('books/', BookListView.as_view()),  # 列表/创建
    path('books/<int:id>/', BookDetailView.as_view()),  # 详情/更新/删除
]
(2)自动路由(适配 ViewSet/ModelViewSet)

通过 DefaultRouter/SimpleRouter 自动生成 RESTful 路由,无需手动写每个 URL:

python 复制代码
# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
# 注册视图集:prefix=路由前缀,viewset=视图类,basename=路由名称前缀(用于reverse)
router.register('books', BookViewSet, basename='book')

urlpatterns = [
    path('', include(router.urls)),  # 自动生成 /books/ 和 /books/{id}/ 路由
]
  • DefaultRouter:比 SimpleRouter 多生成根路由(/),返回所有可用路由的列表;
  • basename:当视图中未定义 queryset 时必须指定,用于生成路由名称。

4. 认证组件(Authentication):验证请求身份

(1)核心作用

验证请求的发起者身份(如用户是否登录、Token是否有效),认证成功后将用户对象赋值给 request.user,未认证则 request.userAnonymousUser

(2)内置认证类
认证类 适用场景 配置方式
BasicAuthentication 简单HTTP基础认证(测试用) authentication_classes = [BasicAuthentication]
TokenAuthentication 基于Token的认证(常用) 需配合 rest_framework.authtoken 应用
SessionAuthentication 基于Django Session的认证 前后端不分离场景(如Django模板+DRF)
JWTAuthentication 基于JWT的认证(主流) 需安装 djangorestframework-simplejwt
(3)实战配置(Token认证)
python 复制代码
# 1. 安装依赖(Token认证需)
# INSTALLED_APPS = [..., 'rest_framework.authtoken']

# 2. 全局配置(settings.py)
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',  # 默认Token认证
        'rest_framework.authentication.SessionAuthentication',  # 兼容Session
    ],
}

# 3. 视图级配置(覆盖全局)
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 仅用Token认证
    authentication_classes = [TokenAuthentication]
(4)获取Token(内置接口)

DRF 提供了获取Token的接口,需在urls.py注册:

python 复制代码
from rest_framework.authtoken import views
urlpatterns += [
    path('api-token-auth/', views.obtain_auth_token),  # POST 用户名/密码获取Token
]

5. 权限组件(Permissions):控制请求访问权限

(1)核心作用

在认证之后,判断当前用户是否有权限执行请求的操作(如普通用户只能读,管理员可修改)。

(2)内置权限类
权限类 作用 适用场景
AllowAny 允许所有用户访问 公开接口(如首页、登录)
IsAuthenticated 仅认证用户可访问 需登录的接口(如个人中心)
IsAdminUser 仅管理员(is_staff=True)可访问 后台管理接口
IsAuthenticatedOrReadOnly 认证用户可读写,未认证仅可读 公开但需登录修改的接口
DjangoModelPermissions 基于Django模型权限(add/change/delete) 符合Django权限体系的接口
(3)实战配置
python 复制代码
# 1. 全局配置(settings.py)
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',  # 默认权限
    ],
}

# 2. 视图级配置(覆盖全局)
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 仅管理员可修改,普通用户仅可读
    permission_classes = [IsAuthenticatedOrReadOnly, IsAdminUser]

# 3. 自定义权限类(核心)
from rest_framework import permissions

class IsBookAuthor(permissions.BasePermission):
    """自定义权限:仅书籍作者可修改/删除"""
    def has_object_permission(self, request, view, obj):
        # 只读请求(GET/HEAD/OPTIONS)允许所有认证用户
        if request.method in permissions.SAFE_METHODS:
            return True
        # 写请求仅作者可执行
        return obj.author == request.user

# 使用自定义权限
class BookViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated, IsBookAuthor]

6. 限流组件(Throttling):控制接口访问频率

(1)核心作用

防止接口被恶意刷取,限制用户/IP在指定时间内的请求次数(如每分钟最多10次请求)。

(2)内置限流类
限流类 作用
AnonRateThrottle 限制未认证用户(按IP)的访问频率
UserRateThrottle 限制认证用户的访问频率
ScopedRateThrottle 按视图的 throttle_scope 区分限流规则
(3)实战配置
python 复制代码
# 1. 全局配置(settings.py)
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',  # 未认证用户:每天100次
        'user': '1000/day',  # 认证用户:每天1000次
    },
}

# 2. 视图级配置
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 自定义视图级限流规则
    throttle_classes = [ScopedRateThrottle]
    throttle_scope = 'books'  # 对应settings中的限流规则

# 3. settings补充Scoped限流
REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['books'] = '50/minute'  # 书籍接口每分钟50次

7. 分页组件(Pagination):处理大数据量列表

(1)核心作用

将大查询集拆分为多页返回,避免一次性返回过多数据导致性能问题。

(2)内置分页类
分页类 特点 适用场景
PageNumberPagination 页码分页(?page=1&page_size=10) 常规列表分页
LimitOffsetPagination 偏移分页(?limit=10&offset=20) 精准定位数据位置
CursorPagination 游标分页(加密游标,只支持排序) 大数据量(百万级)分页
(3)实战配置
python 复制代码
# 1. 全局配置(settings.py)
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,  # 默认每页10条
}

# 2. 自定义分页类(推荐)
from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10  # 默认每页10条
    page_size_query_param = 'page_size'  # 允许客户端自定义每页条数(?page_size=20)
    max_page_size = 100  # 客户端最大可自定义的每页条数

# 视图级使用
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    pagination_class = StandardResultsSetPagination

8. 过滤与排序组件(Filtering & Sorting)

(1)过滤:筛选符合条件的数据

需安装 django-filterpip install django-filter

python 复制代码
# 1. 配置(settings.py)
INSTALLED_APPS = [..., 'django_filters']
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',  # 基础过滤
        'rest_framework.filters.SearchFilter',  # 模糊搜索
    ],
}

# 2. 视图使用
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filterset_fields = ['author', 'price']  # 基础过滤字段(?author=1&price=99)
    search_fields = ['title', 'description']  # 模糊搜索字段(?search=Python)
(2)排序:按指定字段排序
python 复制代码
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['price', 'publish_date']  # 允许排序的字段(?ordering=-price)
    ordering = ['-publish_date']  # 默认排序(按发布时间降序)

三、DRF 进阶特性(提升效率)

1. 异常处理(Exception Handling)

DRF 内置标准化异常处理,可自定义异常响应格式:

python 复制代码
# utils.py
from rest_framework.views import exception_handler
from rest_framework.response import Response

def custom_exception_handler(exc, context):
    # 先调用DRF默认的异常处理
    response = exception_handler(exc, context)
    # 自定义响应格式
    if response is not None:
        response.data = {
            'code': response.status_code,
            'msg': response.data.get('detail', '请求失败'),
            'data': response.data,
        }
    return response

# settings.py
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'utils.custom_exception_handler',
}

2. 版本控制(Versioning)

支持多版本API共存(如 /v1/books//v2/books/):

python 复制代码
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    'DEFAULT_VERSION': 'v1',
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    'VERSION_PARAM': 'version',
}

# urls.py
path('<version>/books/', BookViewSet.as_view()),

# 视图中获取版本
class BookViewSet(ModelViewSet):
    def get_serializer_class(self):
        if self.request.version == 'v1':
            return BookV1Serializer
        return BookV2Serializer

3. 内容协商(Content Negotiation)

DRF 自动根据请求头 Accept 适配响应格式(如 JSON/XML),也可通过URL后缀指定(/books.json):

python 复制代码
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',  # 默认JSON
        'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览器可浏览的界面
    ],
}

四、DRF 最佳实践(避坑指南)

1. 性能优化

  • 序列化器中避免嵌套查询:使用 select_related(外键一对一)/prefetch_related(外键一对多)优化查询集;

    python 复制代码
    class BookViewSet(ModelViewSet):
        def get_queryset(self):
            return Book.objects.all().select_related('author').prefetch_related('tags')
  • 避免序列化器中使用复杂计算字段:可缓存或提前计算;

  • 分页:大数据量接口必须分页,优先用 CursorPagination

2. 代码组织

  • 序列化器:按模型拆分(如 book_serializers.py),复杂序列化器拆分为列表/详情版;
  • 视图:优先用 ModelViewSet,自定义逻辑通过 get_*/perform_* 方法扩展;
  • 权限/认证:自定义类统一放在 permissions.py/authentication.py 中。

3. 安全规范

  • 认证:生产环境禁用 BasicAuthentication,优先用 JWT/Token 认证;
  • 权限:最小权限原则(如普通用户仅可读,作者仅可修改自己的资源);
  • 限流:公开接口必须配置限流,防止刷量;
  • 数据校验:所有客户端传入数据必须通过序列化器校验,禁止直接入库。

4. 测试

DRF 提供 APITestCase 方便测试API:

python 复制代码
from rest_framework.test import APITestCase
from django.contrib.auth.models import User
from .models import Book

class BookAPITest(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(username='test', password='123456')
        self.client.force_authenticate(user=self.user)  # 模拟登录
        self.book = Book.objects.create(title='Test Book', price=99, author=self.user)

    def test_book_list(self):
        response = self.client.get('/books/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data['results']), 1)

五、核心总结

DRF 的知识体系可总结为「1个核心+8大组件+N个进阶特性」:

  • 1个核心:围绕 RESTful 规范,以「请求-响应生命周期」为脉络;
  • 8大组件:序列化、视图、路由、认证、权限、限流、分页、过滤(解决API开发的核心问题);
  • N个进阶:异常处理、版本控制、内容协商等(提升API的健壮性和扩展性)。

学习DRF的关键是「先掌握核心组件的使用,再理解底层原理,最后通过最佳实践优化」------ 优先用 ModelViewSet 快速实现CRUD,遇到自定义需求时,再回退到 APIView/GenericAPIView 扩展,兼顾效率与灵活性。

相关推荐
虹科网络安全1 小时前
艾体宝干货 | Redis Python 开发系列#6 缓存、分布式锁与队列架构
redis·python·缓存
9号达人1 小时前
大家天天说的'银弹'到底是个啥?看完这篇你就明白了
前端·后端·程序员
卿雪1 小时前
缓存异常:缓存击穿、缓存穿透、缓存雪崩 及其解决方案
java·数据库·redis·python·mysql·缓存·golang
无限进步_1 小时前
C语言文件操作函数解析
c语言·开发语言·数据库·c++·后端·visual studio
背心2块钱包邮1 小时前
第3节——differentiation rules(求导法则)
人工智能·python·matplotlib·scipy
white-persist1 小时前
【攻防世界】reverse | answer_to_everything 详细题解 WP
c语言·开发语言·汇编·python·算法·网络安全·everything
程序员爱钓鱼1 小时前
Node.js 编程实战:路径模块(path)详解
后端·node.js·trae
聆风吟º1 小时前
【Spring Boot 报错已解决】告别“Whitelabel Error Page”:Spring Boot 404报错的排查指南
java·spring boot·后端
高频交易dragon1 小时前
python缠论形态分析过程
开发语言·网络·python