2009-05-30 3 views
5

Эй, я хочу сортировать объекты на основе вычисленного значения в django ... как это сделать?как сортировать по вычисленному значению в django

Вот профиль модели Пример пользователя на основе переполнения стека, что объясняет мое затруднительное положение:

class Profile(models.Model): 
    user = models.ForeignKey(User) 

    def get_reputation(): 
     ... 
     return reputation 
    reputation = property(get_reputation) 

Таким образом, сказать, что я хочу, чтобы сортировать пользователей по репутации. Как мне это сделать? Я знаю, что вы не можете просто сделать это:

Profile.objects.order_by("-reputation") 

Спасибо за вашу помощь всем :)

ответ

3

Если вам нужно сделать сортировку в базе данных (потому что у вас есть много записей, и нужны, например, постраничными их), единственный реальный вариантом является, чтобы превратить репутацию в денормализованного поля (например, обновленном в перекрытом save() метод на модели).

+2

+1: просто переопределите save(), чтобы обновить это поле. –

+0

Я решил использовать пост-save сигнал, а не отменять save() ... есть ли какие-либо потенциальные проблемы, о которых я должен знать с этим подходом? – Jiaaro

+0

Если вы хотите использовать сигналы, я бы рекомендовал pre_save, а не post_save. Чтобы сохранить денормализованное поле в актуальном состоянии с помощью post_save, вам нужно выполнить два запроса UPDATE, где их будет достаточно. –

16

Поскольку код вычисления существует только в Python, вы должны выполнить сортировку в Python, а также:

sorted (Profile.objects.all(), key = lambda p: p.reputation) 
+0

эй, это ответ на вопрос, который я задал, но я принял другой, потому что он решил проблему, я имею ... комментарий С.Лотта. Я поднял ваш ответ, хотя :) – Jiaaro

+0

есть ли способ сделать это запрос queryset вместо обычного списка python (или преобразовать список в набор запросов)? – Jiaaro

+0

Это кажется немного тяжелым, чтобы спросить в комментарии, поэтому я переместил его на свой вопрос: http://stackoverflow.com/questions/1058135/django-convert-a-list-back-to-a-queryset – Jiaaro

5

Начиная с Django-1.8, можно отсортировать QuerySet с помощью query expressions, если вычисленное значение может быть отображено в SQL. Вы также можете использовать annotations к модели в качестве термина order_by.

from django.db.models import F 
Profile.objects.annotate(reputation=(F('<field>') + ...)).order_by("-reputation") 

Основные операции, такие как +, -, *, / и ** могут быть использованы с F(). Кроме того, есть несколько других функций, таких как Count, Avg, Max ...

Ссылки:

Смотри также это SO Q & A: Order a QuerySet by aggregate field value

Смежные вопросы