Поскольку в Django> = 1.11 существует Case
и When
, вы можете сделать это более похожим на форму способом, сохранив все преимущества вашего набора запросов:
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')
Это сгенерирует что-то вроде этого:
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')
Я бы предложил использовать это только с небольшим количеством элементов списка, потому что это взрывает запрос к базе данных.
https://docs.djangoproject.com/ko/1.11/ref/models/conditional-expressions/#case