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

相关推荐
一只游鱼10 分钟前
Redis入门(部署、持久化、缓存问题)
数据库·redis·缓存
北城以北88881 小时前
数据库--MySQL数据管理
数据库·mysql
代码的余温1 小时前
Oracle RAC共享存储核心技术
数据库·oracle
float_六七1 小时前
数据库物理外键与逻辑外键全解析
数据库·oracle
大白的编程日记.1 小时前
【MySQL】数据库的基本操作
数据库·mysql·oracle
Jamie Chyi1 小时前
【Oracle经验分享】字符串拼接过长问题的解决方案 —— 巧用 XMLAGG
数据库·oracle
代码的余温1 小时前
Oracle高可用与容灾解决方案
数据库·oracle
乔巴先生243 小时前
LLMCompiler:基于LangGraph的并行化Agent架构高效实现
人工智能·python·langchain·人机交互
张子夜 iiii4 小时前
实战项目-----Python+OpenCV 实现对视频的椒盐噪声注入与实时平滑还原”
开发语言·python·opencv·计算机视觉
小蒜学长5 小时前
基于springboot 校园餐厅预约点餐微信小程序的设计与实现(代码+数据库+LW)
数据库·spring boot·微信小程序