django-voting сортировка по рейтингу
Думаю, многие знакомы с этим расширением, но всё же:
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-* проектов. Очень советую их посмотреть, сбережёте много сил. Это я к тому, что для себя открыл их относительно недавно.