Search code examples
djangodjango-querysetdjango-orm

Django - order ManyToManyField within a queryset result


Simplified Models:

Class Product(models.Model):
    name = models.CharField(max_length=250)
    launch_date = models.DateField(blank=True)

Class Collection(models.Model):
    name = models.CharField(max_length=250)
    products = models.ManyToManyField(Product, related_name="collections", blank=True)

Say I want to return a Collection query but I want products returned with this queryset to be ordered by launch_date, how would I do this?

Just adding order_by on products launch dates to the query does not work as that just orders the collections, but doesn't actually order the products within the collections Collections.objects.order_by('products__launch_date').all()


Solution

  • You can use prefetch_related to optimise DB queries by fetching all related objects in a single query, if you add Prefetch objects to this you can change the queryset used to prefetch including the ordering

    qs = Collection.objects.prefetch_related(
        Prefetch('products', queryset=Product.objects.order_by('launch_date'))
    )
    

    You could also just add default ordering to the model if this ordering is always desired

    class Product(models.Model):
    
        ...
    
        class Meta:
            ordering = ['launch_date']