调用select_related字段的管理器。

12 浏览
0 Comments

调用select_related字段的管理器。

我有以下的示例:

class Profile(models.Model):
    ...
class Person(models.Model):
    profile = models.ForeignKey(Profile, ...)

我有一些复杂的模型管理器用于Profile类,我构建了一个视图以列出大量的Person。我尝试在数据库中计算所有内容,因此我想从Person QuerySet中调用Profile Manager。

为了做到这一点,我需要做如下操作:

Person.objects.filter(...).select_related('profile', queryset=Profile.objects.with_computed_revenue().all())

然后我应该能够从SQL中检索到person.profile.computed_revenue,并且\"with_computed_revenue\"函数是ProfileManager的一个注释computed_revenue的函数。

最终目标是在person queryset中添加:

.values('profile__computed_revenue')

使用Prefetch for prefetch_related似乎是可行的,但我找不到与select_related等效的内容。

admin 更改状态以发布 2023年5月23日
0
0 Comments

要使用自定义查询集与 select_related,您可以使用 prefetch_related 和 Prefetch 对象。

Person.objects.prefetch_related(
    Prefetch('profile', queryset=Profile.objects.with_computed_revenue())
)

但是,这不会使注释在 values() 中可用。

0
0 Comments

如果我正确理解了你的意思,正如Django文档中所述,在https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related

select_related通过创建SQL连接并在SELECT语句中包含相关对象的字段来工作。因此,select_related在同一数据库查询中获取相关对象。但是,为了避免跨“多”关系连接而产生的更大结果集,select_related仅限于单值关系-外键和一对一。

另一方面,prefetch_related针对每个关系进行单独的查找,并在Python中进行“连接”。这使得它能够预取多对多和多对一的对象,而无法使用select_related完成,除外键和一对一关系。

你应该对于FK关系使用select_related,而对于Many-To-One关系使用prefetch_related

在你的情况下,Person模型具有Many-To-One关系到Profile,因此您必须使用prefetch_related

0