[Django]-Django ORM: Perform conditional `order_by`

3👍

You can work with a generic solution that looks like:

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

items = [7, 17, 3]
Foo.objects.alias(
    n_order=Case(
        *[When(n=item, then=Value(i)) for i, item in enumerate(items)],
        default=Value(len(items)),
        output_field=IntegerField()
    )
).order_by('n_order', 'n')

This thus constructs a conditional expression chain [Django-doc] that is used first, and if n is not one of these, it will fall back on ordering with n itself.

2👍

You can use .annotate() to assign records a custom_order value and use then .order_by() to order the queryset based on this value.

For example:

Foo.objects \
.annotate(custom_order=Case( 
    When(n=7, then=Value(0)), 
    When(n=17, then=Value(1)), 
    When(n=3, then=Value(2)),
    default=Value(3),
    output_field=IntegerField()
 ) \
.order_by('custom_order', 'n')

Leave a comment