首页 > 解决方案 > Django获取嵌套相关对象的计数

问题描述

我正在使用Django 2.2

我有三个模型

class LeadList(SafeDeleteModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=128, verbose_name='Lead List Name')

    def entries_count(self):
        return LeadListEntry.objects.filter(
            dynamic_url_object__lead_list=self
        ).count()
class DynamicUrlObject(SafeDeleteModel):
    lead_list = models.ForeignKey(
        LeadList,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        default=None,
        related_name='dynamic_url_object'
    )
class LeadListEntry(models.Model):
    dynamic_url_object = models.ForeignKey(
        'otherapp.DynamicUrlObject',
        on_delete=models.CASCADE,
        related_name='lead_list_entry'
    )
    data = models.TextField(help_text='Lead List entry data. (JSON data)', blank=False)

LeadList中有参考DynamicUrlObjectLeadList可以链接到多个DynamicUrlObject实例。

LeadListEntry链接到DynamicUrlObject以记录每个DynamicUrlObject实例的数据。

我想获得特定的计数LeadListEntryLeadList

为此,我在模型中有一个模型方法LeadList来返回LeadListEntry条目的计数。

但是在获取 的列表时LeadList,它会产生N+1问题,每个对象entries_count都会调用该问题,而每个lead_list对象又会运行查询LeadListEntry以获取计数。

我试图prefetch_related在视图中使用

def get_queryset(self):
    return self.serializer_class.Meta.model.objects.filter(
        user=self.request.user
    ).prefetch_related(
        'dynamic_url_object__lead_list_entry'
    )

但是没有任何好处。

我怎样才能在不遇到问题的情况下获得count每个lead_list对象N+1

标签: djangodjango-querysetdjango-2.2

解决方案


你可以做

ll = LeadList.objects.first()  # some lead list object

le_count = LeadListEntry.objects.filter(dynamic_url_object__lead_list=ll).count()

编辑

您可以像这样使用注释。

from django.db.models import Count


ll = LeadList.objects.annotate(le_count=Count('dynamicurlobject__leadlistentry'))

查询集中的每个对象ll都有一个属性,该属性le_count包含该特定对象的线索列表总数。


推荐阅读