【问题标题】:django query to use annotate with a filter for each annotationsdjango 查询使用带有过滤器的注释来为每个注释
【发布时间】:2013-05-02 09:42:02
【问题描述】:

我有以下数据库模型 -

class ObjectDetail(models.Model):
    title = models.CharField()
    img = models.ImageField()
    description = models.TextField()
    uploaded_by = models.ForeignKey(User, related_name='uploaded_by')


class Vote(models.Model):

    vote_type = models.BooleanField(default = False)
    voted_by =  models.ForeignKey(User, related_name='voted_by')
    voted_for = models.ForeignKey(User, related_name='voted_for')
    shared_object = models.ForeignKey(ObjectDetail, null=True, blank=True)
    dtobject  = models.DateTimeField(auto_now_add=True)

现在,在我看来,我想获取每个对象的赞成票和反对票的数量。

一种方法是在 class ObjectDetails 下添加一个函数 如下 -

    @property
    def upvote(self):
        upvote = Vote.objects.filter(shared_object__id = self.id, 
                             vote_type = True).count()
        return upvote

    @property
    def downvote(self):
        downvote = Vote.objects.filter(shared_object__id = self.id, 
                               vote_type = False).count()
        return downvote 

但这会导致数据库中出现每个对象的两个查询。 另一种方法是使用annotate

obj = ObjectDetail.objects.select_related().filter(FILTER_CONDITION).annotate(upvote=Count('vote'), downvote=Count('Vote')).order_by('-shared_time')

从某种意义上说,上述陈述是错误的,它只是给了我票数,而不管赞成票和反对票。

如果您了解该模型,您可以通过过滤vote__vote_type = True 获得赞成票,并通过vote__vote_type=False 获得反对票

如何在查询语句中添加这两个条件/过滤器?

所以我的主要目标是为每个项目获取upvotedownvote 的两个值,并在模板中进行最少的数据库查询,如果我这样做的话

{{ obj.upvote }} 我可以获得对象的赞成票数,以及类似的反对票。

请告诉我,谢谢。

【问题讨论】:

    标签: python django django-models django-queryset django-orm


    【解决方案1】:

    您是否尝试使用values() 对不同的vote_types 进行分组? https://docs.djangoproject.com/en/dev/topics/db/aggregation/#values

    Vote.objects.select_related().filter(FILTER_CONDITION).values('shared_object', 'vote_type').annotate(vote_count=Count('vote_type'))
    

    此时可以在模板中使用regroup循环ObjectDetailss

    https://docs.djangoproject.com/en/dev/ref/templates/builtins/#regroup

    【讨论】:

    • 如你所见,我有两个东西,upvotedownvote,所以我需要两个不同的值,基于过滤器。你只提到了一个。
    • 据我了解,您想做COUNT(*) FROM tbl_name GROUP BY vote_type 之类的事情,而values() 的目的应该正是这个。
    • 我已经编辑了问题,请重新阅读,感谢您的帮助。
    • 我编辑了我的答案,现在Votes 的计数正确,但您没有循环遍历ObjectDetails。不幸的是,我没有看到任何其他方法可以仅通过一个查询来获取它们。
    猜你喜欢
    • 2012-04-05
    • 2022-01-14
    • 2011-06-04
    • 2018-12-08
    • 2020-05-14
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多