通过foreignkey字段排序对象,而不是外键计数

我正在为请求提出请求和投票功能:

class Request(models.Model):
    title = models.CharField(max_length=255)
    approved = models.BooleanField(default=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

class Vote(models.Model):
    request = models.ForeignKey(Request, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    vote_type = models.BooleanField()

我想通过减少每个请求的不同vote_type(True / False)来按总计投票次数降序排列请求。 含有最高票数到最低票数的命令请求。

我可以通过这种方式进行投票:

Request.objects.order_by('-vote')

但是这只是给了我哪个请求具有最多的外键计数,而不是实际的投票计数。

我可以得到这样的请求的实际投票数:

def get_vote_count(obj):
    return obj.vote_set.filter(vote_type=True).count() - obj.vote_set.filter(vote_type=False).count()

但我无法弄清楚在获取所有请求并在视图中对其进行排序时如何实现此目的。


我认为你可以通过使用条件表达式来实现它。

尝试这个:

from django.db import models

Request.objects.annotate(
    num_of_true_vote_type=models.Count(
        models.Case(When(vote__vote_type=True, then=1), output_field=models.IntegerField())
    ),
    num_of_false_vote_type=models.Count(
        models.Case(When(vote__vote_type=False, then=1), output_field=models.IntegerField())
    ),
    difference=models.F('num_of_true_vote_type') - models.F('num_of_false_vote_type')
).order_by('-difference')

你可以为此使用聚合

r = Request.objects.filter(approved=True, vote__vote_type=True).annotate(total_vote=Count('vote'))

这会为您提供带有approved=TrueRequest QuerySetannotate部分会为您提供额外的attribut total_vote给所有具有vote_type=True相关Vote值计数的Request对象。

不要忘了,它QuerySet所以,看看有多少Votevote_type=True的“第一” Request你做r.first().total_vote

链接地址: http://www.djcxy.com/p/41415.html

上一篇: Ordering objects by foreignkey field and not foreignkey count

下一篇: apply padding to inline element across two lines