Django REST Framework 中 ModelViewSet 的接口方法及参数详解,继承的方法和核心类方法,常用查询方法接口

ops/2025/3/16 23:26:16/

第一部分(ModelViewSet)

一、ModelViewSet 的继承结构

ModelViewSet 继承自以下类:

python">ModelViewSet = (CreateModelMixin +    # 创建RetrieveModelMixin +  # 检索单个UpdateModelMixin +    # 更新DestroyModelMixin +   # 删除ListModelMixin +      # 列表GenericViewSet        # 基础视图集
)

二、默认接口方法及参数

以下方法由 ‌mixins‌ 提供,支持 RESTful 标准操作:

方法名HTTP 方法参数说明作用
list(ListModelMixin)GETself, request, *args, **kwargs获取资源列表

create

(CreateModelMixin)

POSTself, request, *args, **kwargs创建新资源

retrieve

(RetrieveModelMixin)

GETself, request, *args, **kwargs (需 pk 或 slug)获取单个资源

update

(UpdateModelMixin)

PUT/PATCHself, request, *args, **kwargs (需 pk 或 slug)全量/部分更新资源

destroy

(DestoryModelMixin)

DELETEself, request, *args, **kwargs (需 pk 或 slug)删除资源
参数统一说明:
  • request‌: Django 请求对象,包含请求数据 (request.data) 和用户信息 (request.user)。
  • *args‌: URL 中捕获的位置参数(如路径参数)。
  • ==‌**‌==kwargs: URL 中捕获的关键字参数(如 pk=1)。

三、核心类方法及参数详解

以下方法由 GenericViewSet 和 GenericAPIView 提供,用于控制视图行为:

方法名参数返回值作用
get_queryset()无参数,但可通过 self.request 访问请求上下文QuerySet返回默认查询集(可覆盖以实现动态过滤)
get_object()无参数,从 URL 参数中提取 pk 或 slug模型实例获取单个对象,支持 lookup_field 自定义查询字段
get_serializer()instance=None, data=None, many=False, partial=False, **kwargs序列化器实例(serializer初始化序列化器,用于请求数据验证和响应数据生成(对需要更新的数据进行验证并返回验证后的数据)
get_serializer_class()无参数,但可通过 self.action 判断当前动作(如 create/update序列化器类动态选择序列化器(例如不同动作使用不同序列化器)
perform_create()serializer (序列化器实例)无,直接保存对象到数据库在创建对象前/后执行额外操作(如设置 created_by=request.user
perform_update()serializer (序列化器实例)无,直接更新对象到数据库在更新对象前/后执行额外操作(如记录日志)
perform_destroy()instance (要删除的模型实例)无,直接删除对象在删除对象前/后执行额外操作(如级联删除关联数据)
filter_queryset()queryset (基础查询集)过滤后的 QuerySet应用所有已配置的过滤器(如 DjangoFilterBackend

四、关键参数扩展说明

1. get_object() 的底层参数
  • lookup_field‌: 默认是 'pk',可通过类属性修改为其他字段(如 slug)。
  • lookup_url_kwarg‌: 默认与 lookup_field 相同,指定从 URL 中提取参数的名称。

示例:

python">class BookViewSet(ModelViewSet):lookup_field = 'isbn'  # 模型字段lookup_url_kwarg = 'book_isbn'  # URL 参数名
2. get_serializer() 的参数
  • instance‌: 要更新的模型实例(用于 update 操作)。
  • data‌: 请求数据(request.data)。
  • partial‌: 是否允许部分更新(True 对应 PATCH 请求)。
    • 从请求参数中获取'partial'标识,当值为True时表示PATCH请求(部分更新字段),False时表示PUT请求(完整更新)。通过控制该参数,DRF的序列化器会决定是否进行全字段验证。

五、权限与节流相关方法

方法名参数作用
get_permissions()返回权限类列表(如 [IsAuthenticated]
get_throttles()返回节流类列表(如 [UserRateThrottle]

六、自定义场景示例

1. 动态过滤查询集
python">def get_queryset(self):# 只返回当前用户创建的书籍return Book.objects.filter(created_by=self.request.user)
2. 按动作选择序列化器
python">def get_serializer_class(self):if self.action == 'list':return BookListSerializerreturn BookDetailSerializer
3. 记录操作日志
python">def perform_create(self, serializer):book = serializer.save(created_by=self.request.user)log_action('create', self.request.user, book)

七、完整方法调用流程图

python">sequenceDiagramparticipant Clientparticipant ViewSetClient->>ViewSet: HTTP 请求 (如 GET /books/)ViewSet->>ViewSet: determine_action()ViewSet->>ViewSet: get_queryset()ViewSet->>ViewSet: filter_queryset()ViewSet->>ViewSet: get_serializer()ViewSet->>ViewSet: perform_动作()ViewSet->>Client: 返回 Response

 

二部分(查询filter)

一、模型关系假设

python"># models.py
class PracticeType(models.Model):p_type = models.CharField(max_length=50)  # 练习类型字段is_active = models.BooleanField(default=True)class QuestionGroup(models.Model):name = models.CharField(max_length=100)g_type = models.ForeignKey(PracticeType, on_delete=models.CASCADE)  # 外键关联created_at = models.DateTimeField(auto_now_add=True)class Question(models.Model):group = models.ForeignKey(QuestionGroup, on_delete=models.CASCADE, related_name='questions')content = models.TextField()score = models.IntegerField()

二、查询方法详解(表格)

方法示例代码参数说明作用描述
filter()QuestionGroup.objects.filter(g_type__p_type='数学')g_type__p_type: 跨模型查询 PracticeType.p_type 字段筛选 p_type 为 "数学" 的题组
QuestionGroup.objects.filter(created_at__year=2024)created_at__year: 提取日期字段的年份筛选 2024 年创建的题组
exclude()QuestionGroup.objects.exclude(g_type__is_active=False)g_type__is_active: 排除关联模型中 is_active=False 的题组排除关联到非激活练习类型的题组
order_by()QuestionGroup.objects.order_by('-created_at', 'g_type')-created_at: 按创建时间倒序;g_type: 按外键的默认排序(如 p_type先按创建时间倒序,再按练习类型排序
values()QuestionGroup.objects.values('id', 'g_type__p_type')id: 返回题组 ID;g_type__p_type: 返回关联练习类型的 p_type 字段获取题组 ID 及其关联的练习类型名称
annotate()QuestionGroup.objects.annotate(total_score=Sum('questions__score'))total_score=Sum('questions__score'): 计算每个题组下所有题目的总分为每个题组添加总分注解字段 total_score
QuestionGroup.objects.annotate(avg_score=Avg('questions__score'))avg_score=Avg('questions__score'): 计算每个题组下题目的平均分为每个题组添加平均分注解字段 avg_score

三、参数详细说明

1. ==‌filter(**‌==kwargs) - 过滤
  • 参数语法‌: 字段__操作符=值(如 created_at__year=2024
  • 跨模型查询‌: 使用双下划线 __ 跳转关联模型字段(如 g_type__p_type)。
  • 示例‌:
    python">
    # 查询 p_type 为 "物理" 的题组
    groups = QuestionGroup.objects.filter(g_type__p_type='物理')# 查询 2023 年之后创建的题组
    groups = QuestionGroup.objects.filter(created_at__year__gte=2023)
2. ==‌exclude(**‌==kwargs) - 排除
  • 参数语法‌: 同 filter(),但排除满足条件的对象。
  • 示例‌:
    python">
    # 排除关联到非激活练习类型的题组
    groups = QuestionGroup.objects.exclude(g_type__is_active=False)# 排除 p_type 为 "化学" 的题组
    groups = QuestionGroup.objects.exclude(g_type__p_type='化学')
3. ‌order_by(*fields)‌ - 排序
  • 参数语法‌: 字段名前加 - 表示倒序(如 -created_at)。
  • 跨模型排序‌: 支持按关联模型字段排序(如 g_type__p_type)。
  • 示例‌:
    python">
    # 按练习类型名称升序,再按创建时间倒序
    groups = QuestionGroup.objects.order_by('g_type__p_type', '-created_at')
4. ‌values(*fields)‌ - 取字段
  • 参数语法‌: 指定要返回的字段或关联字段(如 g_type__p_type)。
  • 返回结果‌: 字典列表(而非模型对象)。
  • 示例‌:
    python">
    # 获取所有题组的 ID、名称及其关联的练习类型名称
    data = QuestionGroup.objects.values('id', 'name', 'g_type__p_type')
5. ‌annotate(别名=聚合函数)‌ - 注解
  • 参数语法‌: 使用聚合函数(如 CountSumAvg)生成计算字段。
  • 跨模型聚合‌: 通过关联模型的 related_name(如 questions)访问子对象。
  • 示例‌:
    python">
    from django.db.models import Count, Sum, Avg# 统计每个题组的问题数量
    groups = QuestionGroup.objects.annotate(question_count=Count('questions'))# 计算每个题组的总分和平均分
    groups = QuestionGroup.objects.annotate(total_score=Sum('questions__score'),avg_score=Avg('questions__score')
    )

四、高级用法

1. 链式调用
python"># 查询 2024 年创建的数学题组,按总分降序排列
groups = QuestionGroup.objects.filter(g_type__p_type='数学',created_at__year=2024
).annotate(total_score=Sum('questions__score')
).order_by('-total_score')
2. 跨多级模型查询
python"># 查询所有题目分数大于 80 的题组
groups = QuestionGroup.objects.filter(questions__score__gt=80)
3. 空值处理
python"># 查询没有关联任何问题的题组
groups = QuestionGroup.objects.filter(questions__isnull=True)

五、性能优化

  • select_related‌: 用于外键或一对一字段的预加载(减少查询次数)。
    python">
    # 预加载 g_type 关联的 PracticeType 对象
    groups = QuestionGroup.objects.select_related('g_type').filter(g_type__p_type='数学')
  • prefetch_related‌: 用于多对多或一对多字段的预加载。
    python"># 预加载题组下的所有问题
    groups = QuestionGroup.objects.prefetch_related('questions').annotate(total_score=Sum('questions__score'))

 


http://www.ppmy.cn/ops/166342.html

相关文章

【python】OpenCV—Hough Circle Transform

文章目录 1、功能描述2、代码实现3、效果展示4、完整代码5、涉及到的库函数6、参考 更多有趣的代码示例,可参考【Programming】 1、功能描述 2、代码实现 载入必要的库 import sys import cv2 as cv import numpy as np函数入口 if __name__ "__main__&qu…

Ubuntu 服务器安装 Python 环境 的详细指南

以下是 在 Ubuntu 上安装 Python 3.10 的详细步骤(兼容 Ubuntu 20.04/22.04): 方法一:通过 PPA 仓库安装(推荐) 1. 添加 deadsnakes PPA sudo apt update sudo apt install software-properties-common s…

数据结构篇——线性表

一、引入 线性结构是数据结构中最为重要的一种数据存储结构之一,同时也是其他数据结构的基础。今天我们就来学学数据结构中的一种基础类型——线性表。 二、线性表的定义和特点 线性表的定义:用数据元素的有限序列表示。具体情况如下图所示:…

HarmonyOS学习第20天:让应用“找准方向”的地图与定位秘籍

引言:开启 HarmonyOS 应用的位置感知之旅 在这个信息爆炸的时代,我们的生活与地理位置信息紧密相连。无论是寻找一家心仪的餐厅,规划一次完美的旅行,还是追踪快递的实时位置,地图与定位服务都扮演着至关重要的角色。对…

idea maven 编译报错Java heap space解决方法

1.增加 Maven 编译的堆内存 我是用这个方法修改成功的 Maven 编译时使用的 JVM 堆内存可以通过设置 MAVEN_OPTS 环境变量来调整。 在 IntelliJ IDEA 中设置: 打开 IntelliJ IDEA 的设置(File -> Settings 或 Ctrl Alt S)。 导航到 Bui…

【DevOps】Backstage介绍及如何在Azure Kubernetes Service上进行部署

【DevOps】Backstage介绍及如何在Azure Kubernetes Service上进行部署 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 【DevOps】Backstage介绍及如何在Azure Kubernetes Service上…

MySQL小练习

要求: 新建产品库mydb6_product,新建4张表如下: oemployees表 列1:id,整型,主键 列2:name,字符串,最大长度50,不能为空 列3:age,整型 …

【Go学习】04-3-Gorm框架-初识模型定义

【Go学习】04-3-Gorm框架-初识模型定义 初识Gorm创建工作区数据准备操作数据 模型定义模型定义模型标签表名映射Model数据库连接DSN连接数据库调试模式连接池配置 初识Gorm gorm地址:https://github.com/go-gorm/gorm 对开发者友好的gorm库,目前使用最…