Since there exists Case
and When
in Django >= 1.11 you can do it in a more orm-like way keeping all the benefits of your queryset:
from django.db import models
order = ['b', 'a', 'z', 'x', 'c']
_whens = []
for sort_index, value in enumerate(order):
_whens.append(
models.When(my_field=value, then=sort_index)
)
qs = MyModel.objects.annotate(
_sort_index=models.Case(
*_whens,
output_field=models.IntegerField()
)
)
qs.order_by('_sort_index')
This will generate something like this:
from django.db import models
order = ['b', 'a', 'z', 'x', 'c']
qs = MyModel.objects.annotate(
_sort_index=models.Case(
models.When(my_field='b', then=0),
models.When(my_field='a', then=1),
models.When(my_field='z', then=2),
models.When(my_field='x', then=3),
models.When(my_field='c', then=4),
output_field=models.IntegerField()
)
).order_by('_sort_index')
I would suggest to use this only with a small amount of list-items because it blows up the database-query.
https://docs.djangoproject.com/ko/1.11/ref/models/conditional-expressions/#case