>我有一个配置文件模型,其中包含一个名为与Stock
相关的ManyToMany
字段。在我的管理仪表板中,我正在尝试显示每只股票所在的监视列表数量。我的注释查询是:
qs.annotate(watchlist_count=Count('profile__watchlist__symbol'))
但它返回了不正确的结果
以下是模型:
class Profile(models.Model):
user = OneToOneField(User, on_delete=models.CASCADE)
watchlist = ManyToManyField(Stock, blank=True)
def __str__(self):
return self.user.email
class Stock(models.Model):
symbol = CharField(max_length=15, unique=True)
name = CharField(max_length=100)
category = CharField(max_length=30, choices=CATEGORY_CHOICES, blank=True)
about = TextField(help_text='About this company')
def __str__(self):
return f'{self.symbol} - {self.name}'
等效的 SQL 查询为:
select stock_id, count(stock_id) from api_profile_watchlist group by stock_id;
我的注释查询有什么问题?
你做了太多的联接。通过在多对多关系上加入两次,您可以"炸毁"计数。
您可以使用该Stock
简单地计算监视列表的数量,使用:
from django.db.models import Count
Stock.objects.annotate(
watchlist_count=Count('profile')
)
这是有效的,因为默认情况下,related_query_name=…
[Django-doc] 具有模型的名称(如果您指定了模型,则具有related_name
)。因此,您从Stock
到Profile
的隐式关系(watchlist
关系中Profile
到Stock
的反向关系)是profile
(小写)。因此,我们要求 Django 计算给定Stock
对象与Profile
的关系数。