[Django]-Django query โ€“ Is it possible to group elements by common field at database level?

11๐Ÿ‘

โœ…

You can do this. Hope this helps.

Review.objects.values('book__name').annonate(average=Avg('rating'))

UPDATE:

If you want all the ratings of a particular book in a list, then you can do this.

from collections import defaultdict
ratings = defaultdict(list)
for result in Review.objects.values('book__name', 'rating').order_by('book__name', 'rating'):
    ratings[result['book__name']].append(result['rating'])

You will get a structure like this :

[{ book__name: [rating1, rating2, ] }, ]

UPDATE:

q = Review.objects.values('book__name').annonate(average=Avg('rating')).filter().prefetech_related('rating')
q[0].ratings.all() # gives all the ratings of a particular book name
q[0].average # gives average of all the ratings of a particular book name

Hope this works (Iโ€™m not sure, sorry), but you need to add related_ name attribute

class Review(models.Model):
     book = models.ForeignKey(Book, related_name='rating')

UPDATE:

Sorry to say, but you need something called as GROUP_CONCAT in SQL , but it is not supported in Django ORM currently.

You can use Raw SQL or itertools

from django.db import connection
sql = """
    SELECT name, avg(rating) AS average, GROUP_CONCAT(rating) AS rating
    FROM book JOIN review on book.id = review.book_id
    GROUP BY name
     """
cursor = connection.cursor()
cursor.execute(sql)
data = cursor.fetchall()

DEMO

๐Ÿ‘คAnish Shah

Leave a comment