_set 在 Django 中用于查询集

Posted

技术标签:

【中文标题】_set 在 Django 中用于查询集【英文标题】:_set in Django for a queryset 【发布时间】:2017-06-24 04:00:14 【问题描述】:

我有点困惑如何在 Django 的 QuerySet 中使用 _set。例如,一个对象博客b,以及由属性entry_set 关联的对象Entryb.entry_set.all()是什么意思?

如果有人可以使用此示例显示可能的输出,我将不胜感激。

【问题讨论】:

【参考方案1】:

您看到的是reverse related object lookup。

在你的例子中:

class Blog(models.Model):
    pass

class Entry(..):
    blog = Blog(..)

现在,给定Entry 类型的对象e,您将执行e.blog 来访问相关对象Blog - 这是一个正向关系。 _set 是 django 为您提供的反向查找类变量。

所以,给定对象 b - 你会这样做:

entries = b.entry_set.all()

反向是查询集的原因是,ForeignKey 是1-to-many 关系。因此,反向是一个查询集。

_set 对象在 related_name is not specified 时可用。

【讨论】:

我们能不能只说 entry = b.entry.all() 以及如果我们这样做会发生什么。只是想了解“设置”的作用? 你阅读解释了吗?你也浏览过链接吗? 不得不读了几遍。我猜“_set”这个词实际上并没有设置任何东西,而是“获取”所有相关的对象。我就是这么理解的。 考虑在查询集中设置而不是getter和setter【参考方案2】:

简单地说:

假设您有一个模型Car 和一个模型WheelWheelCar 的外键关系如下:

class Car(models.Model):
    pass

class Wheel(models.Model):
    car = models.ForeignKey(Car, on_delete=models.CASCADE) # on_delete parameter is mandatory in Django 2.0

假设wWheel 的一个实例,而cCar 的一个实例:

>>> w.car # returns the related Car object to w
>>> c.wheel_set.all() # returns all Wheel objects related to c

详细解释

使用上面定义的模型,Wheel 对象w 可以通过访问car 属性获得其关联的Car 对象:w.car

如果模型具有ForeignKey,则该模型的实例将可以通过模型的简单属性访问相关的 foreign 对象。

据官方Django documentation:

Django 还为关系的“另一端”创建 API 访问器——从相关模型到定义关系的模型的链接。

在这种情况下,Car 对象c 可以通过wheel_set 属性访问所有相关Wheel 对象的列表:c.wheel_set.all()

如果模型具有ForeignKey,则外键模型的实例将有权访问返回第一个模型的所有实例的Manager。默认情况下,此Manager 被命名为FOO_set,其中FOO 是源模型名称,小写。这个Manager 返回QuerySets,可以过滤和操作。

【讨论】:

任何线索为什么它是wheel_set 而不是Wheel_set?为什么不区分大小写? @DevanshSharma,这是因为这是您在字段声明中未指定 related_name 时的默认行为。它使用<model_name>_set 作为related_name (see more) 的默认值。 Here 可以看到类名是小写的,所以不是Wheel_set

以上是关于_set 在 Django 中用于查询集的主要内容,如果未能解决你的问题,请参考以下文章

覆盖 Django admin 中的默认查询集

django查询集-17

Django更改查询集字段不影响数据库

注释不同的 Django 查询集不再使用不同的查询集

用于迭代嵌套结果的 Django 查询集预取优化

包含列表中所有值的 Django 反向查询集