Голосование в стиле Reddit с помощью django

Эй, мне нужно вручную внедрить систему голосования в модель.

Мне очень помог Майк Дезимоун в этой работе, но мне нужно расширить его работу.

Вот мой текущий код

Просмотр

def show_game(request):
    game = Game.objects.get(pk=1)
    discussions = game.gamediscussion_set.filter(reply_to=None)
    d = {
        'game':game,
        'discussions':discussions
    }
    return render_to_response('show_game', d)

Шаблон

<ul>
    {% for discussion in discussions %}
    {{ discussion.html }}
    {% endfor %}
</ul>

Модель

class GameDiscussion(models.Model):
    game = models.ForeignKey(Game)
    message = models.TextField()
    reply_to = models.ForeignKey('self', related_name='replies', null=True, blank=True)
    created_on = models.DateTimeField(blank=True, auto_now_add=True)
    userUpVotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')
    userDownVotes = models.ManyToManyField(User, blank=True, related_name='threadDownVotes')

    def html(self):
        DiscussionTemplate = loader.get_template("inclusions/discussionTemplate")
        return DiscussionTemplate.render(Context({
            'discussion': self,
            'replies': [reply.html() for reply in self.replies.all()]
    }))

Шаблон обсуждения

<li>
    {{ discussion.message }}
    {% if replies %}
        <ul>
            {% for reply in replies %}
                {{ reply }}
            {% endfor %}
        </ul>
    {% endif %}
</li>

Как вы можете видеть, у нас есть 2 поля userUpVotes и userDownVotes в модели, они будут вычислять, как упорядочивать обсуждения и ответы.

Как мне реализовать эти 2 поля, чтобы упорядочить ответы и обсуждения на основе голосов?

Любая помощь была бы замечательной!

ИЗМЕНИТЬ

Я добавил в свою модель метод под названием vote_difference

    def vote_difference(self):
        return int(self.userUpVotes.count()) - int(self.userDownVotes.count())

Я могу использовать это в своих шаблонах, чтобы получить текущий голос, однако я не могу использовать это в моем файле view.py для сортировки по этому значению, есть ли способ включить это значение в мое представление?

ИЗМЕНИТЬ (2)

Я медленно добираюсь до этого, мне нужно аннотировать 2 поля и сделать для них вычисления, однако кажется, что я не могу выполнять базовые математические вычисления с помощью annotate.

Любые идеи?

    discussions = game.gamediscussion_set.filter(reply_to=None).annotate( score= (Count('userUpVotes') - Count('userDownVotes')) ).order_by('-score')

person dotty    schedule 01.06.2010    source источник
comment
Итак, как далеко вы зашли в этом?   -  person meder omuraliev    schedule 07.11.2010


Ответы (4)


Алгоритм Reddit основан на формуле для расчета силы тяжести. Я нашел его на этом веб-сайте

Алгоритм Reddit

let t = (t1 – epoch)

(где t1 - время публикации сообщения)

let x be the number of up votes minus the number of down votes.

Потом,

let y be:
  • 1, если голосов за больше, чем голосов против,
  • -1 Если голосов «против» больше, чем голосов «за»,
  • 0, если есть такие же числа.

Теперь позвольте

z = max({x,1})

И у нас есть

ranking = C log10(z) + yt1

Where C is a constant (C = 45000).
person Jon Winstanley    schedule 01.06.2010
comment
Хэй, спасибо за ответ, он, безусловно, добавляет немного понимания того, как работает Reddits. Однако, похоже, вы упустили суть. Моя модель имеет 2 поля (userUpVotes и userDownVotes), я буду определять разницу между этими значениями, чтобы определить, как упорядочить свои обсуждения. У userUpVotes может быть 8 пользователей, тогда как у userDownVotes может быть 2. Таким образом, окончательное голосование будет userUpVotes - userDownVotes, которое в этом случае может быть +6. Теперь мне нужна помощь, как добавить поля userDownVotes и userUpVotes, убрать их друг от друга и упорядочить на основе этого. - person dotty; 01.06.2010
comment
Извините за то, что не связали алгоритм с Django, я чувствовал, что эта информация поможет, хотя я понял, что она не отвечает на вопрос. - person Jon Winstanley; 02.06.2010

Вы можете захотеть немного денормализовать вашу модель, добавив vote_score целочисленное поле.

Затем все, что вам нужно сделать, это переопределить save(), чтобы вычислить счет с помощью вашего vote_difference() метода.

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

person Chris Lawlor    schedule 02.06.2010

Я знаю, что это не прямой ответ на ваш вопрос. Но просмотр кода reddit может быть очень полезным. Это помогло мне, когда мне пришлось реализовать полуинтеллектуальный алгоритм обрезки изображений, аналогичный Reddit.

person Vasil    schedule 01.06.2010
comment
Обратной стороной является то, что он использует структуру пилонов, а не django :( - person dotty; 01.06.2010

Я выпустил приложение для голосования под названием qhonuskan-Votes, вы можете проверить его здесь: https://github.com/miratcan/qhonuskan-votes

person Mirat Can Bayrak    schedule 28.02.2012