Django: get most frequent objects in many to many relationship

37 Views Asked by At
class SoundItem(models.Model):
    name = models.CharField(max_length=200)

class SoundCategory(models.Model):
    name = models.CharField(max_length=200)

class SoundItemReview(models.Model):
    sound = models.ForeignKey(SoundItem, on_delete=models.CASCADE, related_name='sound_reviews')
    categories = models.ManyToManyField(SoundCategory, related_name="sound_reviews")

For one instance of sound item (s), I can get its reviews with s.sound_reviews.all(), but how I count most frequent categories in its reviews (without having to manually iterate reviews and count categories)?

Eg for s there are 2 reviews:
review1: category1, category2
review2: category2, category3
then I want to get {"category2": 2, "category1": 1, "category3": 1}
1

There are 1 best solutions below

3
willeM_ Van Onsem On BEST ANSWER

You an order the SoundCategorys by the number of items:

from django.db.models import Count

SoundCategory.objects.alias(nitem=Count('sound_reviews')).order_by('-nitem')

or when related to a single SoundItem item:

from django.db.models import Count

SoundCategory.objects.filter(sound_reviews__sound=my_sound_item).alias(
    nitem=Count('sound_reviews')
).order_by('-nitem')