4

私はDjangoが初めてです。RedditやHacker Newsのように、完全にスレッド化され、各コメントを上下投票でソートするディスカッションアプリをDjangoで構築しようとしています。

私は 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) でソートされる方法でそれを行う方法です。賛成票。

これら 2 つの問題に関するヘルプをいただければ幸いです。

mptt などの別の方法を使用してコメント ツリーを作成することにオープンです。

ありがとう!

編集: 私は、以下の非常にハックっぽい独自のソリューションを考え出しました。この質問を回答済みとしてマークするつもりはありません。これは、本番環境で使用するようなソリューションではないと思うからです (そして、これを本番環境で使用しないことを望んでいます)。しかし、誰かが解決策を探していた場合に備えてこれが役立つことを願っています:

私の 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