Django REST框架核心:GenericAPIView详解

Django REST framework (DRF)GenericAPIView 的源码核心部分。

  • 它是所有"泛型视图"的基础类,比如常用的 ListAPIViewRetrieveAPIViewCreateAPIView 都是继承自它。

🌟 作用

  • 继承自 APIView,因此仍然是一个标准的 DRF 视图。

  • 提供了常用的"通用逻辑":

    • 统一获取 queryset
    • 统一获取 serializer
    • 提供 对象查找get_object
    • 提供 分页paginate_queryset / get_paginated_response
    • 提供 过滤filter_queryset
  • 它本身不实现 get/post/put/delete 等 HTTP 方法,而是作为"基类"让子类在此之上去扩展。

🔑 关键点解析

1. querysetget_queryset

python 复制代码
def get_queryset(self):
    assert self.queryset is not None
    queryset = self.queryset
    if isinstance(queryset, QuerySet):
        queryset = queryset.all()  # 确保每次请求都是新 QuerySet
    return queryset
  • 必须设置 queryset 或重写 get_queryset
  • 一般推荐重写 get_queryset 来根据 用户/请求参数 动态返回不同数据。
  • 注意不要直接用 self.queryset,否则会因为缓存导致跨请求数据不一致。

2. serializer_classget_serializer_class

python 复制代码
def get_serializer(self, *args, **kwargs):
    serializer_class = self.get_serializer_class()
    kwargs.setdefault('context', self.get_serializer_context())
    return serializer_class(*args, **kwargs)
  • 必须指定 serializer_class 或重写 get_serializer_class
  • 可以根据用户角色、请求方法等动态选择不同序列化器。

3. get_object

python 复制代码
def get_object(self):
    queryset = self.filter_queryset(self.get_queryset())
    lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
    filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
    obj = get_object_or_404(queryset, **filter_kwargs)
    self.check_object_permissions(self.request, obj)
    return obj
  • 用来获取某一个具体对象(常用于 RetrieveAPIViewUpdateAPIView)。
  • 默认按 pk 查找,可以改 lookup_field = 'slug' 之类。
  • 自动做 权限检查

4. 过滤与分页

  • filter_queryset(queryset):遍历 filter_backends,按配置的 filter backend 处理,比如 DjangoFilterBackendSearchFilterOrderingFilter
  • paginate_queryset(queryset):按 pagination_class 分页,比如 PageNumberPagination
  • get_paginated_response(data):返回带分页信息的 Response。

✅ 使用示例

比如写一个获取用户文章的 API:

python 复制代码
from rest_framework.generics import ListAPIView, RetrieveAPIView
from .models import Article
from .serializers import ArticleSerializer

class ArticleListView(ListAPIView):
    serializer_class = ArticleSerializer

    def get_queryset(self):
        # 只展示当前用户的文章
        return Article.objects.filter(author=self.request.user)

class ArticleDetailView(RetrieveAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = "slug"   # 用 slug 查找

这样 ListAPIView / RetrieveAPIView 都是基于 GenericAPIView 实现的。


👉 总结:
GenericAPIView 本身不会直接用,而是作为"可复用的基类",把 queryset / serializer / 过滤 / 分页 / 查找对象 的逻辑抽象好,供其他泛型视图使用。

相关推荐
cd9888011 小时前
2026年,电销机器人哪家强?
python
搏博11 小时前
多传感器融合基础之一图像空间(Image Space)全面解析
图像处理·python·图像空间·融合感知
2601_9618752411 小时前
花生十三公考课程|网课|视频
数据库·windows·git·svn·eclipse·github
2601_9618752411 小时前
花生十三资源盘|电子版|全科
python·django·flask·virtualenv·scikit-learn·pygame·tornado
郝学胜-神的一滴11 小时前
完全二叉树与堆底层原理深度剖析 | 手写C++大顶堆实现
java·开发语言·数据结构·c++·python·算法
WangN211 小时前
【通识】宇树G1_29DOF速度跟踪训练—逐章学习手册
人工智能·python·学习·机器人·具身智能
l1t11 小时前
DeepSeek总结的parquet Variant “碎形化“技术
数据库·parquet
装不满的克莱因瓶12 小时前
掌握语义分割经典模型 FCN——从像素分类到端到端分割的奠基之作
人工智能·python·深度学习·算法·机器学习·分类·数据挖掘
云计算磊哥@12 小时前
运维开发宝典030-MySQL06数据库运维阶段总结
运维·数据库·运维开发
这个DBA有点耶12 小时前
国产数据库有哪些?2026年主流产品选型对比
数据库·程序人生·职场和发展·架构·程序员创富·改行学it