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

news/2025/3/13 9:26:59/

第一部分(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/news/1578754.html

相关文章

llama.cpp编译

llam.cpp编译 1. 下载&编译 git clone https://github.com/ggml-org/llama.cpp cmake -S . -B build2. 下载模型验证 # 下载地址 https://huggingface.co/filipealmeida/open-llama-7b-v2-open-instruct-GGUF/blob/main/ggml-model-Q4_0.gguf# 验证 ./llama-cli.exe -m …

qt5中使用中文报错error: C2001: 常量中有换行符

1.qt5中使用中文报错error: C2001: 常量中有换行符 如这条代码: this->ui->pbtn_open_card->setText("关闭卡");运行时报错,提示常量中有换行符 2.工具->选项->文本编辑,选择下图 3.重新按utf-8加载编码 4.文件开头添加 #pr…

InternVL:论文阅读 -- 多模态大模型(视觉语言模型)

更多内容:XiaoJ的知识星球 文章目录 InternVL: 扩展视觉基础模型与通用视觉语言任务对齐1.概述2.InternVL整体架构1)大型视觉编码器:InternViT-6B2)语言中间件:QLLaMA。3)训练策略(1&#xff09…

适合于金融系统开发者的书籍大全

以下是一些推荐的书籍,适合技术开发者: 《Accounting for Software Developers》(作者:Mark G. OBrien) 这本书专门为软件开发者撰写,介绍了会计原则和复式记账的基本概念,并将其与软件开发相结…

用C# Newtonsoft.Json库实现JSON数据中某个字段值的提取

在C#中,可以使用Newtonsoft.Json库(也称为Json.NET)来处理JSON数据。这个库提供了非常方便的方法来解析和操作JSON数据。下面将通过几个示例来展示如何从JSON格式的文本中提取某个字段的值,并将其存储到字符串、列表或其他泛型集合…

Kerckhoffs原理

Kerckhoffs原理 1. 核心定义 Kerckhoffs原理(也称为Kerckhoffs准则)由荷兰密码学家Auguste Kerckhoffs于19世纪提出,是现代密码学设计的核心原则之一。其核心思想是: 一个密码系统的安全性应完全依赖于密钥的保密性,而…

【透视国家的三维棱镜:技术、制度与文化的解构与重构】

透视国家的三维棱镜:技术、制度与文化的解构与重构 一、技术层:文明的物质显影剂 技术作为生存密码 青铜器冶炼技术将部落联盟升级为商周王朝,蒸汽机将农耕文明扭转为工业文明,半导体技术正在重塑21世纪权力版图。技术是文明存续的…

大语言模型对软件工程师的影响曲线

最近刷到一篇有意思的文章,讨论了大语言模型(LLM)对软件工程师影响的职级曲线。文章提出了一个观点:大语言模型对工程师的帮助并非均匀的,而是随着职级变化呈现出类似U型的曲线。 以工程师的职级差异视角出发&#xff…