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

发布于 2024-10-11 02:54:41 字数 644 浏览 5 评论 0原文

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

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

I have three models, Contender, Week and Vote, each contender can have votes based on week,

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)

I would like to add something to the Contender, so I did this:

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

the problem is that when I add a vote with another Week (that has diferent date_start) the .vote_count value is changes and thus it seems like the extra parameters I pass to the Count object does not matter.

How do I do this type of annotation in the Django ORM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱你是孤单的心事 2024-10-18 02:54:41

你可以从投票开始:

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

如果你这样做,性能会更有效经常统计。

You could start from Vote:

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)

Also, you can do some denormalization - add

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

and count votes in it (overriding Vote.save() or using post_save signal), then you will just do:

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

It will be much more efficient performancewise if you do such statistics often.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文