Sec*_*ter 8 django aggregate sum
我正在尝试创建一个显示产品列表的Django站点,并按照他们收到的总票数对它们进行排序."产品"是一个类,"投票"是另一个类,其中一个名为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)
Run Code Online (Sandbox Code Playgroud)
这是我的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))
Run Code Online (Sandbox Code Playgroud)
所以你看到我得到与每个产品相关的投票得分总和,然后将这个数字分配给每个产品的'total_votes'字段,然后根据'total_votes'重新排序产品列表.
但是,结果并不像预期的那样,产品与投票分数分开订购.有人可以告诉我这里的代码有什么问题吗?而且,这是解决这个问题的正确方法吗?
谢谢
Dan*_*man 12
这似乎是一种不必要的复杂方式.您将单独汇总每个产品的投票,将结果保存在产品中,然后按这些投票金额进行排序.
而不是那样,似乎你应该一气呵成:
product_list = Product.objects.annotate(total_votes=Sum('vote__score')).order_by('total_votes')
Run Code Online (Sandbox Code Playgroud)
(我假设你的初始引用sentence并且b分别是指product和p- 否则你需要提供更多有关这些实际内容的详细信息.)