Думаю, многие знакомы с этим расширением, но всё же:
На самом деле, рейтинг извлекается запросом:
Конечно, можно пойти в лоб и сделать что-то типа:
«Много раз» символизирует необходимость использовать менеджеры… Скажем, Article.objects это и есть менеджер. Зная это, можно написать своё. Вопрос только в том, как определить id типа? Это задача contenttype фреймворка. Думаю, проще привести код менеджера:
Оригинал: "django-voting сортировка по рейтингу"
P.S> Вообще, на google code есть достаточно количество django-* проектов. Очень советую их посмотреть, сбережёте много сил. Это я к тому, что для себя открыл их относительно недавно.
django-voting позволяет ввести оценку любой сущности по digg-принципу (+1/-1) максимум за 30 минут (с учётом включения асинхронных запросов JS).Но есть одна плохая особенность: отсутствие возможности сортировать сущности по рейтингу стандартными средствами ORM. Далее опишу как это реализовал я.
Сайт проекта: django-voting.googlecode.com
На самом деле, рейтинг извлекается запросом:
SELECT SUM(vote) FROM votes WHERE content_type_id=? AND object_id=?Где следует указать id типа (contenttype framework) и id объекта.
Конечно, можно пойти в лоб и сделать что-то типа:
Article.objects.extra(select={'score': 'SELECT SUM(vote) FROM votes WHERE content_type_id=? AND object_id=?'})Но это, ИМХО, длинновато, особенно если нужно это делать много раз.«Много раз» символизирует необходимость использовать менеджеры… Скажем, Article.objects это и есть менеджер. Зная это, можно написать своё. Вопрос только в том, как определить id типа? Это задача contenttype фреймворка. Думаю, проще привести код менеджера:
class ScoreOrderManager(models.Manager):
def select_score(self):
""" Выбрать результаты голосования по объекту """
from django.contrib.contenttypes.models import ContentType
model_type = ContentType.objects.get_for_model(self.model)
table_name = self.model._meta.db_table
return self.extra(select={'score': 'SELECT SUM(vote) FROM votes WHERE content_type_id=%i AND object_id=%s.id' % (int(model_type.id), table_name)})Далее подключаем менеджер к объекту, просто добавив свойство (можно переопределить objects) со значением = экземпляру менеджера.class Article:
title = models.CharField(max_length=200)
...
mymanager = ScoreOrderManager()Далее, всё работает по принципу:Article.mymanager.select_score().order_by('-score')Единственная проблема, select_score нужно вызывать непосредственно у менеджера. У QuerySet такого свойства нет. (готов выслушать предложения на этот счёт)Оригинал: "django-voting сортировка по рейтингу"
P.S> Вообще, на google code есть достаточно количество django-* проектов. Очень советую их посмотреть, сбережёте много сил. Это я к тому, что для себя открыл их относительно недавно.