我是Django的新手。我试图在Django中构建一个讨论应用程序,像Reddit和Hacker News一样,是完全线程化的,并通过上/下投票对每个评论进行排序。
我一直在使用django-voting app,并希望尽可能继续使用它。
我的models.py的简化版本是:
Class Comment(models.Model):
text = models.TextField()
user = models.ForeignKey(User)
parent = models.ForeignKey('self', related_name='children', null=True, blank=True)
因为我正在使用django-voting应用程序,所以我可以得到"得分" (upvotes减去downvotes)任何特定的评论,如:
comment = Comment.objects.get(pk=1) # Grab the comment with primary key = 1
score = Vote.objects.get_score(comment)["score"]
我无法弄清楚如何: (a)在一个视图中准备数据,格式可以转换为模板中的线程讨论,以及 (b)如何以一种按赞成分类的方式这样做。
非常感谢对这两个问题的任何帮助。
我愿意使用另一种方法,比如mptt来构建评论树 - 但我仍然不清楚如何在django-mptt app中通过upvote进行排序。
谢谢!
修改 我已经提出了我自己的,非常黑客的解决方案。我不打算将这个问题标记为已回答,因为我不认为这是在生产中使用的那种解决方案(我希望自己不会在生产中使用它)。但是,万一有人在寻找 解决方案,我希望这有用:
在我的views.py中,我创建了一个函数,在给定对象的查询集的情况下通过投票输出排序列表:
def list_sorted_by_score(query_set):
sorted_score_list = []
# First, I create a list of all the objects with their associated scores
for object in query_set:
# django-voting's get_score outputs a dictionary that looks like:
# {"score": score, "num_votes": num_votes}
score_dict = Vote.objects.get_score(object)
sorted_score_list.append({"object": object, "score": score_dict["score"], "num_votes": score_dict["num_votes"]})
# Then, I sort that list of dictionaries by the "score"
sorted_score_list.sort(key=lambda x:x["score"], reverse=True) # This sorts by score, highest to lowest (reverse=False is lowest to highest)
return sorted_score_list
我使用该功能按分数对所有顶级评论进行排序。所以我的上下文变量只包括按分数排序的评论,没有父母 - 即:
top_level_comments = list_sorted_by_score(Comment.objects.filter(parent=None))
在我的models.py中,我定义了一个方法来获取给定注释的子节点的list_sorted_by_score:
def score_list_children(self):
children = self.children.all()
sorted_score_list = []
for object in children:
score_dict = Vote.objects.get_score(object)
sorted_score_list.append({"object": object, "score": score_dict["score"], "num_votes": score_dict["num_votes"]})
sorted_score_list.sort(key=lambda x:x["score"], reverse=True)
return sorted_score_list
最后,我为单个评论制作了一个模板," comment.html。"简化版本如下:
<div class="comment">
{{ comment.object.text }}
{# note that I must use the comment**.object**, since
that's how I constructed my list_sorted_by_score list of dictionaries #}
{% for child in comment.object.score_list_children %}
{% with filename="comment.html" %} {# hack to get around Django throwing a maximum recusion error #}
{% include filename with comment=child %}
{% endwith %}
{% endfor %}
</div>
可能很明显,这是非常黑客的。我仍然非常有兴趣听到人们在现实世界中尝试过的真实解决方案。