4

我是 Django 的新手。我正在尝试在 Django 中构建一个讨论应用程序,就像 Reddit 和 Hacker News 一样,它是完全线程化的,并通过赞成/反对投票对每个评论进行排序。

我一直在使用 django-voting 应用程序,如果可能的话,我想继续使用它。

我的 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 应用程序,所以我可以获得任何特定评论的“分数”(赞成票减去反对票),如下所示:

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 应用程序中通过 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>

很明显,这是相当骇人听闻的。我仍然对听到人们在现实世界中尝试过的真实解决方案非常感兴趣。

4

0 回答 0