Django注释返回重复条目
Posted
技术标签:
【中文标题】Django注释返回重复条目【英文标题】:Django annotate returning duplicate entries 【发布时间】:2021-12-26 08:50:23 【问题描述】:我正在像这样注释查询集:
class ItemQuerySet(models.QuerySet):
def annotate_subitem_stats(self):
return self.annotate(
count_subitems=Count('subitems'),
has_sent_subitems=Case(
When(subitems__status=Status.sent, then=Value(True)),
default=Value(False)
),
)
在本例中,SubItem
是一个模型,其外键指向 Item
。
当我运行此代码时发生了一个奇怪的行为。假设我们有 1 个Item
和 2 个SubItem
s 链接到它。一个子项已发送状态,而另一个则没有。当我在查询集上运行注释时,查询集返回该项目两次,一次将has_sent_subitems
设置为True
,另一次设置为False
。另一个奇怪的是,一个重复有count_subitems == 1
,另一个有count_subitems == 1
,好像查询集已经将项目分成两行,一个在status == 'sent'
,另一个在status != 'sent'
。
这基本上就是带注释的查询集的样子:
[
'name': 'Item Name',
'count_subitems': 1,
'has_sent_subitem': False
,
'name': 'Item Name',
'count_subitems': 1,
'has_sent_subitem': True
]
这是数据库的样子,使用伪代码:
item = Item()
SubItem(item=item, status=draft)
SubItem(item=item, status=sent)
我很确定这与When(subitems__status=Status.sent, then=Value(True)),
行有关。有什么办法可以让那行检查是否只有 1 个项目已发送状态,然后将注释设置为 true 并继续?
附:使用 .distinct()
不起作用。我不能使用.distinct(field)
,因为annotate() + distinct(fields) is not implemented.
【问题讨论】:
【参考方案1】:您可以改为使用Exists
子查询,以避免subitems__status
引起的连接,所以:
from django.db.models import Exists, OuterRef
class ItemQuerySet(models.QuerySet):
def annotate_subitem_stats(self):
return self.annotate(
count_subitems=Count('subitems'),
has_sent_subitems=Exists(
SubItem.objects.filter(item=OuterRef('pk'), status=Status.sent)
),
)
【讨论】:
我想知道,由于SubItem.objects.filter
调用,这是否会触发查询集中每个项目的查询?
不应该,因为子查询仍然是“主”查询的一部分以上是关于Django注释返回重复条目的主要内容,如果未能解决你的问题,请参考以下文章