2014-01-30 112 views
0

首先,祝中国新年快乐。Django根据相关对象对查询集进行排序

我这个问题,我正在寻找排序查询集的好方法:

的三个实体:Service, Order, Rating

A Service对象可以有多个Order对象,一个Order对象只能有一个Rating对象。 现在,我想根据它的平均Rating排名a Service

最直接的答案是: 第一次查询的Service所有Orders并计算其平均Rating,然后根据平均评分排序Service

但是,我很担心效率和响应。

所以,我想在Service对象中应该有一个属性:Average_Rating。每次创建评论时,Average_Rating都会更新。

此方法是提高响应速度的好方法吗?如果是这样,那么实施它的最好方法是什么?谢谢。

+0

这是更好地看到比解释的代码,请张贴代码为您楷模。 –

+0

虽然没有代码可以查看,但基本上我明白你在说什么。事实上,我认为“直截了当”的解决方案并不是那么糟糕。重点是每次想要对服务进行排名时都会发生额外的计算。对于第二种解决方案,即添加新属性,每次创建评论时都会进行额外的计算。此外,平均评级计算并不昂贵,因为您可以在一分贝命中和o(n)时间内完成评分。 –

回答

1

如果你不想反规范化,你可以使用annotation

假设你的模型是这样的:

class Service(models.Model): 
    name = models.CharField(max_length=5) 

class Order(models.Model): 
    name = models.CharField(max_length=5) 
    service = models.ForeignKey(Service) 

class Rating(models.Model): 
    order = models.OneToOneField('Order') 
    grade = models.IntegerField() 

然后你就可以用平均标注和查询:

Service.objects.annotate(avg_rate=Avg('order__rating__grade')).order_by('avg_rate') 
+0

嗨,伊兰。谢谢!它似乎工作。还有一个问题,如果评级与订单之间的关系是一对多关系(一个订单有很多评论),那么如何应用这种方法呢? –

+0

Afaik。完全一样 – eran

+0

谢谢!到目前为止,这是我见过的最简单的解决方案。 –

相关问题