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 / 过滤 / 分页 / 查找对象 的逻辑抽象好,供其他泛型视图使用。

相关推荐
KaiwuDB12 分钟前
KWDB 分布式架构探究——数据分布与特性
数据库·分布式
于越海18 分钟前
Python工程师向项目管理转型的深度分析与学习道路规划
笔记·python·学习
笨蛋不要掉眼泪24 分钟前
Spring Boot集成腾讯云人脸识别实现智能小区门禁系统
java·数据库·spring boot
二闹1 小时前
discard和remove的那些事儿
python
大志说编程1 小时前
LangChain框架入门18: 十分钟带你搞定LLM工具调用
python·langchain·ai编程
Leiwenti1 小时前
MySQL高阶篇-数据库优化
数据结构·数据库·mysql
你的电影很有趣1 小时前
lesson44:Redis 数据库全解析:从数据类型到高级应用
数据库·redis·缓存
NineData2 小时前
2025 DTCC大会来了,NineData联合创始人周振兴将分享《AI重塑数据库管理模式》的主题演讲
数据库
NineData2 小时前
NineData亮相2025中国数据库技术大会,并荣获《年度优秀技术团队奖》
数据库
AI视觉网奇3 小时前
麒麟系统播放图片 速度比较
开发语言·python·pygame