Pull to refresh

django-voting сортировка по рейтингу

Reading time 2 min
Views 2.1K
Думаю, многие знакомы с этим расширением, но всё же:
django-voting позволяет ввести оценку любой сущности по digg-принципу (+1/-1) максимум за 30 минут (с учётом включения асинхронных запросов JS).
Сайт проекта: django-voting.googlecode.com
Но есть одна плохая особенность: отсутствие возможности сортировать сущности по рейтингу стандартными средствами ORM. Далее опишу как это реализовал я.
На самом деле, рейтинг извлекается запросом:
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-* проектов. Очень советую их посмотреть, сбережёте много сил. Это я к тому, что для себя открыл их относительно недавно.
Tags:
Hubs:
+17
Comments 15
Comments Comments 15

Articles