Упорядочение набора запросов Django по возвращенным результатам метода - PullRequest
13 голосов
/ 03 августа 2011

Допустим, у меня есть набор запросов, над которыми Билл работал следующим образом:

test=Things.objects.filter(user='Bill')

Теперь я хочу отсортировать все эти вещи по дате, когда они были назначены для выставления счета.К сожалению, дата назначения не является полем в модели Thing .Вместо этого есть метод с именем thing_date () , который вычисляет его и возвращает дату.Например, следующее:

Thingobject.thing_date()

... возвращает дату.Я думаю, что я хочу сделать что-то вроде:

test=Things.objects.filter(user='Bill').order_by(self__thing_date())

... но я знаю, что это не сработает.Есть ли другой способ?

Обновление

Не удивительно, что другие люди уже шли по этому пути раньше. Ссылка

Ответы [ 2 ]

21 голосов
/ 04 августа 2011

Если 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 в базу данных, иначе у вас будут проблемы с памятью.

10 голосов
/ 04 ноября 2015

см. Эти ответы, чтобы использовать вычисленное значение для сортировки 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...