djangodjango-ormdjango-related-manager

Django: get most frequent objects in many to many relationship


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}

Solution

  • 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')