QuerySet по совокупному значению поля - PullRequest
28 голосов
/ 24 января 2009

Допустим, у меня есть следующая модель:

class Contest:
    title = models.CharField( max_length = 200 )
    description = models.TextField()

class Image:
    title = models.CharField( max_length = 200 )
    description = models.TextField()
    contest = models.ForeignKey( Contest )
    user = models.ForeignKey( User )

    def score( self ):
        return self.vote_set.all().aggregate( models.Sum( 'value' ) )[ 'value__sum' ]

class Vote:
    value = models.SmallIntegerField()
    user = models.ForeignKey( User )
    image = models.ForeignKey( Image )

Пользователи сайта могут представить свои изображения на несколько конкурсов. Тогда другие пользователи могут голосовать за них вверх или вниз.

Все отлично работает, но теперь я хочу отобразить страницу, на которой пользователи могут видеть все вклады в определенный конкурс. Изображения должны быть упорядочены по их оценке. Поэтому я попробовал следующее:

Contest.objects.get( pk = id ).image_set.order_by( 'score' )

Как я и опасался, это не сработает, поскольку 'score' - это не поле базы данных, которое можно использовать в запросах.

Ответы [ 3 ]

47 голосов
/ 24 января 2009

О, конечно, я забыл о новой поддержке агрегирования в Django и ее annotate функциональности.

Таким образом, запрос может выглядеть так:

Contest.objects.get(pk=id).image_set.annotate(score=Sum('vote__value')).order_by( 'score' )
9 голосов
/ 24 января 2009

Вы можете написать свой собственный вид на Python очень просто.

def getScore( anObject ):
    return anObject.score()
objects= list(Contest.objects.get( pk = id ).image_set)
objects.sort( key=getScore )

Это хорошо работает, потому что мы отсортировали список, который мы собираемся предоставить шаблону.

2 голосов
/ 24 января 2009

Уровень базы данных order_by не может отсортировать набор запросов методом python модели.

Решение состоит в том, чтобы ввести поле score в модель Image и пересчитывать его при каждом обновлении Vote. Какая-то денормализация. Когда вы сможете сортировать по нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...