django - 是否可以用复杂的查询来注释 Django ORM 查询

标签 django django-models django-orm

我有三个模型,Contender、Week 和 Vote,每个竞争者都可以根据周进行投票,

class Contender(models.Model)
   week = models.ManyToManyField(Week)

class Week(models.Model):
   date_start = models.DateField()

class Vote(models.Model):
   contender = models.ForeignKey(Contender)
   week = models.ForeignKey(Week)

我想向 Contender 添加一些内容,所以我这样做了:

c = Count('vote', vote__week__date_start = "2011-01-03")
contenders = Contender.objects.all().annotate(vote_count=c).order_by('-vote_count')
contenders[0].vote_count

问题是,当我在另一周(具有不同的 date_start)添加投票时,.vote_count 值会发生变化,因此我传递给 Count 对象的额外参数似乎并不重要。

如何在 Django ORM 中进行此类注释?

最佳答案

您可以从投票开始:

votes = Vote.objects.filter(week__date_start = "2011-01-03")      \
                    .values_list('contender')                     \
                    .annotate(cnt=Count('week')).order_by('-cnt')
contender_pks = [d[0] for d in votes]
contenders_dict = Contender.objects.in_bulk(contender_pks)

contenders = []
for pk, vote_count in votes:
    contender = contenders_dict[pk]
    contender.vote_count = vote_count
    contenders.append(conteder)

此外,您还可以进行一些非规范化 - 添加

class VoteCount(models.Model):
   contender = models.ForeignKey(Contender)
   week = models.ForeignKey(Week)
   count = models.IntegerField(default=0)

并在其中计票(覆盖 Vote.save() 或使用 post_save 信号),然后你只需执行以下操作:

VoteCount.objects.filter(week__date_start = "2011-01-03") \
                 .select_related('contender')             \
                 .order_by('-count')

如果您经常进行此类统计,性能将会更加高效。

关于django - 是否可以用复杂的查询来注释 Django ORM 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4630349/

相关文章:

django - 使用 URLField 优于 TextField 的优势?

django - 在 Django ORM 的子查询中返回多个值

Django不删除cookie

python - Django 默认缓存

python - Statsd - 跨堆栈跟踪时间

django - 在 Django 中调试查询集

python - 值错误 : invalid literal for int( ) with base 10: '262,400,000'

Django 教程 selection_set

python - Django Rest Framework - 自动注释查询集

django - 如何删除 django 请求中的重复项