Заказ набора запросов Django по возвращенным результатам метода
Скажем, у меня есть набор запросов, с которыми Билл работал так:
test=Things.objects.filter(user='Bill')
Теперь я хочу отсортировать все эти вещи по дате, когда они были назначены на счет. К сожалению, дата назначения не поле в модели Thing. Вместо этого существует метод с именем thing_date(), который показывает его и возвращает дату. Например, следующее:
Thingobject.thing_date()
... возвращает дату. Я предполагаю, что я хочу сделать, это что-то вроде:
test=Things.objects.filter(user='Bill').order_by(self__thing_date())
... но я знаю, что это не сработает. Есть ли другой способ?
Update
Неудивительно, что раньше люди шли по этой дороге. Ссылка
Ответы
Ответ 1
Если thing_date()
является функцией в коде python, вы не можете получить базу данных для сортировки по ней. Это означает, что нет смысла размещать запрос. Вам нужно будет отсортировать результаты после того, как вы их получите в python. Это будет хорошо, если вы не имеете дело с очень большим количеством объектов.
qs = Things.objects.filter(user='Bill')
unsorted_results = qs.all()
sorted_results = sorted(unsorted_results, key= lambda t: t.thing_date())
Если у вас очень большое количество Things
, вам нужно будет каким-то образом получить thing_date
в базе данных, иначе у вас будут проблемы с памятью.
Ответ 2
см. эти ответы, чтобы использовать вычисленное значение для сортировки QuerySet
:
В принципе, если thing_date()
можно определить с помощью выражения запроса, вы можете использовать его для аннотации и поиска набора запросов.
from django.db.models import F
from django.utils import timezone
test = Things.objects.filter(user='Bill').annotate(
thing_date=(F('<date field>') - timezone.now()) # some computation
).order_by('thing_date')