[Answered ]-Iterating over results, sorted by a m2m



Iโ€™d just do it the expensive way and cache the result over scratching my head. Your template example would work fine until performance becomes an issue in generating that one page per X cache timeout.

You could do it in python as well if the result set is small enough:

# untested code - don't have your models
from collections import defaultdict

results = defaultdict(list)
for location_m2m in Location.neighborhoods.through.objects.all() \ # line wrap
        .select_related('neighborhood', 'location', 'location__company__name'):

    if location_m2m.location not in results[location_m2m.neighborhood]:

# sort now unique locations per neighborhood
map(lambda x: x.sort(key=lambda x: x.location.company.name), results.values())

# sort neighborhoods by name
sorted_results = sorted(results.items(), key=lambda x:x[0].name)


create another model that would define your m2m relationship:

class ThroughModel(models.Model):
    location = models.ForeignKey('Location')
    neighborhood = models.ForeignKey('Neighborhood')

and use it as the through model for your m2m field:

class Location(models.Model):
    neighborhoods = models.ManyToManyField(Neighborhood, through='ThroughModel')

Then you can get all your neighbourhoods sorted:


This is untested.

Or, if you cannot change the database, just do a raw SQL join.


Leave a comment