Wei Xu
Wei Xu

Reputation: 1659

Django sort queryset according to related objects

First, happy Chinese new year.

I got this problem and I am searching for a good way to sort queryset:

The are three entities: Service, Order, Rating.

A Service object can have many Order objects, an Order object can only have one Rating object. Now, I want to rank the a Service according to its average Rating.

The most straight-forward answer will be: first query all Orders of Service and calculate its average Rating, then sort the Service according to average rating.

However, I am worried about the efficiency and responsiveness.

So, I am thinking that there should be an attribute in the Service object: Average_Rating. And every time a review is created, the Average_Rating is updated.

Is this method a good way to improve responsiveness? If so, what is the best way to implement it? Thank you.

Upvotes: 0

Views: 298

Answers (1)

eran
eran

Reputation: 6931

If you don't want to denormalize, you can use annotation.

Assume your models are something like:

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()

Then you can annotate and query by the average:

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

Upvotes: 1

Related Questions