Django order_by many to many relation

Viewed 1145

How would one go about ordering a queryset by whether or not a many to many relationship condition is true?

i.e.

class Publication(models.Model):
    name = models.CharField(max_length=100)
    books = models.ManyToManyField(Book)

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.CharField(max_length=100)

I would like to make a queryset along the lines of

Publication.objects.all().order_by('books__name'='Awesome Book')

So that the first items would be the Publication which contains a Book with the title "Awesome Book" and then in the end you have all the Publication's which do not have the book.

1 Answers

Here's one approach that can work, create a new field to sort by which maps your logical expression to a numerical value.

from django.db.models import Case, When, Value, IntegerField

Publication.objects.annotate(
    ordering=Case(
        When(books__name="Awesome Book", then=Value(0)),
        default=Value(1),
        output_field=IntegerField(),
    )
).order_by("ordering")
Related