Reddit стиль голосование с Джанго
Вопрос
Сено мне нужно передать влезу в реализацию системы голосования в модель.
У меня была огромная рука помощи от Mike Desimone делает эту работу в первую очередь, но мне нужно расширить его работу.
Вот мой текущий код
Вид
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()]
}))
ОбсуждениеTemplate
<li>
{{ discussion.message }}
{% if replies %}
<ul>
{% for reply in replies %}
{{ reply }}
{% endfor %}
</ul>
{% endif %}
</li>
Как видите, у нас есть 2 поля USERUPVOTES и UserDownVotes на модели, они рассчитают, как заказать обсуждения и ответы.
Как бы я осуществил эти 2 поля, чтобы заказать ответы и обсуждения на основе голосов?
Любая помощь была бы здоровой!
РЕДАКТИРОВАТЬ
Я добавил метод моей модели под названием Vog_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')
Решение
Алгоритм 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 Если есть больше вниз VOTS, чем до голосов,
- 0 Если есть тот же номер.
Сейчас давай
z = max({x,1})
И у нас есть
ranking = C log10(z) + yt1
Where C is a constant (C = 45000).
Другие советы
Вы можете немного подумать о денормализации вашей модели, добавив vote_score
Целочисленное поле.
Тогда все, что вам нужно сделать, это переопределить save()
рассчитать счет, используя ваш vote_difference()
метод.
Это делает сортировку намного проще, и, вероятно, уменьшает количество вызовов баз данных, которые вы делаете.
Я знаю, что это не прямой ответ на ваш вопрос. Но заглянуть в Код Reddit может быть очень полезным. Это помогло мне, когда мне пришлось реализовать полуинтецинтный алгоритм обрезки изображения, похожий на Reddit's.
Я выпустил заявку на голосование под названием Qhonuskan-голоса, вы можете проверить это отсюда: https://github.com/miratcan/qhonuskan-votes.