Django REST框架核心:GenericAPIView详解

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

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

🌟 作用

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

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

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

🔑 关键点解析

1. queryset 和 get_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_class 和 get_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
  • 用来获取某一个具体对象(常用于 RetrieveAPIView、UpdateAPIView)。
  • 默认按 pk 查找,可以改 lookup_field = 'slug' 之类。
  • 自动做 权限检查。

4. 过滤与分页

  • filter_queryset(queryset):遍历 filter_backends,按配置的 filter backend 处理,比如 DjangoFilterBackend、SearchFilter、OrderingFilter。
  • 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 / 过滤 / 分页 / 查找对象 的逻辑抽象好,供其他泛型视图使用。

相关推荐
梦想画家25 分钟前
SQLMesh Python 模型入门(三):前后置语句、蓝图建模与避坑指南
大数据·python·sqlmesh
通信瓦工29 分钟前
利用浊度和电导率测量确定乙二醇基流体的质量
网络·数据库·ai
迅猛龙办公室1 小时前
Python实现绘制同切圆
开发语言·python
小马同学-1 小时前
mysql数据库原理
数据库·mysql
东方护航数据恢复(深圳)1 小时前
政务信创案例:达梦 DM8 数据库掉电页损坏,48 小时修复实录【东方护航数据恢复深圳店】
数据库·数据恢复·it运维·服务器数据恢复·二次开盘·硬盘开盘
言乐61 小时前
Python语音检索
开发语言·python·django·virtualenv·pygame
泡茶喝茶写代码2 小时前
A股量化数据工程:从 REST 接口到策略信号(第 1 篇):指数列表与实时行情接入
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据接口
happylifetree2 小时前
Python34-35:核心语法-流程控制语句-循环-综合案例
python
AC赳赳老秦2 小时前
OpenClaw 数据引用规范自动生成:为公开数据构建可信来源标注与标准引用体系
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
吃饱了得干活2 小时前
Agent 的记忆与工具:从上下文窗口到 MCP
python·agent·mcp