是否可以使用复杂查询注释Django ORM查询

时间:2011-01-07 21:13:38

标签: django django-models django-orm

我有三种模式,竞争者,周和投票,每个竞争者都可以根据周进行投票,

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)

我想向竞争者添加一些东西,所以我这样做了:

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中进行这种类型的注释?

1 个答案:

答案 0 :(得分:3)

你可以从投票开始:

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')

如果经常进行此类统计,那么在性能方面会更有效率。

相关问题