【问题标题】:Ordering a query by aggregate sum in Django, but not getting result as expected在 Django 中按聚合总和排序查询,但未按预期获得结果
【发布时间】:2012-03-05 22:24:27
【问题描述】:

我正在尝试创建一个显示产品列表的 Django 站点,并根据他们收到的总票数对它们进行排序。 'Product' 是一个类,'Vote' 是另一个类,有一个称为 score 的字段,可以是 1、0 或 -1。我希望根据与每个特定产品相关的投票得分总和来订购产品。

这是我的models.py:

class Product(models.Model):
    Content = models.TextField()
    creation_date = models.DateTimeField( default=datetime.now )
    total_votes = models.IntegerField( default=0 )

    def __unicode__(self):
            return self.content

class Vote(models.Model):
        voter = models.ForeignKey( User )
        product = models.ForeignKey( Product )
        score = models.IntegerField( default=0, choices=VOTE_SCORE_CHOICES)
        def __unicode__(self):
                return '%s - %s : %s' % (self.product.id, self.voter, self.score)

这是我的views.py:

def show_products( request):
        product_list = Product.objects.all()

        # set the field 'total_votes' in prduct to the sum of votes for each sentence
        for p in product_list:
                try:
                        v  = Vote.objects.filter( product = p ).aggregate(Sum('score'))['score__sum']
                except IndexError:
                        v  = 0
                p.total_votes = v
        p.save()

        # get the product that has the highest vote score
        try:
                top_product = product_list.order_by('-total_votes')[0].content
        except IndexError:
                top_product = 'no product'

        # reorder product_list according to total_votes
        product_list = product_list.order_by('total_votes')

        return render_to_response('product/product_detail.html',
                        {'product_list': product_list,
                                'top_produce': top_product,}, context_instance=RequestContext(request))

所以你看到我得到了与每个产品相关的投票得分的总和,然后将此数字分配给每个产品的“total_votes”字段,然后根据“total_votes”重新排序产品列表。

但是,结果并不如预期,产品的订购与投票分数分开。有人可以告诉我这里的代码有什么问题吗?而且,这是处理这个问题的正确方法吗?

谢谢

【问题讨论】:

    标签: django sum aggregate


    【解决方案1】:

    这似乎是一种不必要的复杂方法。您正在分别汇总每个产品的投票,将结果保存在产品中,然后按这些投票总和进行排序。

    取而代之的是,您似乎应该一口气完成所有操作:

    product_list = Product.objects.annotate(total_votes=Sum('vote__score')).order_by('total_votes')
    

    (我假设您对sentenceb 的初始引用分别是指productp - 否则您需要提供有关这些实际含义的更多详细信息。)

    【讨论】:

    • 哦,好的。谢谢丹尼尔。我会尝试一下。它似乎过于复杂。是的,最初对 sentence 和 b 的引用是指 product 和 p (有一堆名称不佳的字段,并决定重命名它们以使问题更清楚。忘记更改这两个。现在修复)跨度>
    • Daniel,你的方法奏效了,而且绝对是一种更好的方法。顺便说一句,我意识到之前的问题是我没有缩进 p.save(),所以它没有将它包含在 for 循环中。
    猜你喜欢
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多