Reddit стиль голосования с Джанго - PullRequest
6 голосов
/ 01 июня 2010

Слушай, мне нужно передать систему голосования в модель.

У меня была огромная рука помощи от Майка ДеСимона, которая делала эту работу в первую очередь, но мне нужно расширить его работу.

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

View

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)

Template

<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()]
    }))

DiscussionTemplate

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

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

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

Любая помощь будет отличной!

EDIT

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

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

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

РЕДАКТИРОВАТЬ (2)

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

Есть идеи?

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

Ответы [ 4 ]

4 голосов
/ 02 июня 2010

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

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

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

3 голосов
/ 01 июня 2010

Алгоритм 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).
1 голос
/ 28 февраля 2012

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

1 голос
/ 01 июня 2010

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

...