
前の記事「FastAPIブログにコメントシステムを追加する」では、FastAPIブログに基本的なコメントシステムを追加し、ユーザーが投稿について議論できるようになりました。
しかし、これらのコメントは一方通行でした。他の人はあなたの投稿にコメントできましたが、あなたは彼らのコメントに返信することができませんでした。
コメントセクションをよりインタラクティブにするために、この記事ではブログのコメント返信機能を実装します。ユーザーは既存のコメントに返信できるようになり、これらの返信は階層関係を明確に示すためにネストされた(またはインデントされた)形式で表示されます。
ステップ1:データモデルの更新
返信機能を実装するには、コメント間に親子の関係を確立する必要があります。返信は基本的にコメントですが、「親コメント」があります。これは、Comment
モデルに自己参照関係を追加することで実現します。
1. Comment モデルの編集
models.py
ファイルを開き、Comment
モデルにparentId
、parent
、replies
属性を追加します。
parentId
:comment
テーブル自体にid
を指す外部キーとして機能するオプションのフィールドです。トップレベルのコメントの場合、parentId
はNone
になります。parent
およびreplies
: これらはRelationship
を使用してComment
モデル内の親子関係を定義します。これにより、comment.replies
を介してコメントへのすべての返信に簡単にアクセスできます。
main.py
でcreate_db_and_tables
関数を自動的にモデルの変更を検出し、アプリケーション起動時にデータベーススキーマを更新するように構成したため、SQLを手動で実行する必要はありません。
手動でSQLを実行する必要があり、データベースがLeapcell で作成された場合、

そのグラフィカルインターフェイスから簡単にSQLステートメントを実行できます。ウェブサイトのデータベース管理ページにアクセスし、SQLインターフェイスにステートメントを貼り付けて実行するだけです。

ステップ2:コメントサービスの調整
サービスレイヤーは、新しいコメントを作成する際に親コメントを関連付け、クエリを実行する際にコメントのフラットなリストをツリー構造に構造化するように調整する必要があります。
comments_service.py
を開き、以下の変更を行います。
ロジックの説明:
get_comments_by_post_id
は、投稿のすべてのコメント(トップレベルと返信の両方)を取得し、structure_comments
を呼び出して処理します。- 新しい
structure_comments
メソッドがこのロジックの中核となります。すべてのコメントを反復処理します。コメントにparentId
がある場合、その親のreplies
配列に追加されます。ない場合はトップレベルのコメントです。この関数は最終的に、すべてトップレベルのコメントのリストを返します。各コメントは、返信のネストされたリストが含まれている可能性があります。 create_comment
メソッドは、オプションのparent_id
パラメータを追加します。このIDが提供されている場合、新しく作成されたコメントは対応する親コメントに関連付けられます。
ステップ3:ルートの更新
コントローラーは、リクエストボディからオプションのparentId
を受信し、それをサービスに渡す必要があります。この変更は非常に簡単です。
routers/comments.py
を開きます。
ステップ4:フロントエンドビューのアップグレード
これが最も変更が多い部分です。コメントとその返信を再帰的にレンダリングするためにpost.html
テンプレートを更新する必要があり、動的に返信フォームを表示するためのJavaScriptも追加する必要があります。
1. コメントテンプレートの作成
コメントの再帰的レンダリングを達成するには、再利用可能な「マクロ」を作成するのが最善です。
templates
ディレクトリに_comment.html
という名前の新しいファイルを作成します。
このテンプレートはrender_comment_tree
という名前のマクロを定義します。渡されたcomments
配列を反復処理し、各コメントのreplies
配列に対して再帰的に自分自身を呼び出し、depth
をインクリメントして視覚的なインデントを作成します。
2. post.html
の更新
次に、templates/post.html
を編集してこの新しいマクロを使用し、対応するJavaScriptロジックを備えたユニバーサル返信フォームを追加します。
JavaScriptロジックの説明:
- ページには1つのコメントフォームしかありません。
- ユーザーがコメントの「返信」ボタンをクリックすると、JavaScriptはそのコメントのIDを取得し、フォームの隠し
parentId
入力フィールドの値として設定します。 - 同時に、フォーム全体を返信対象のコメントの直後に移動させ、フォームのタイトルを更新して、ユーザーに明確なコンテキストを提供します。
- 返信時には「返信をキャンセル」ボタンが表示されます。これをクリックすると、フォームがリセットされ、コメントセクションの最下部に戻されます。
実行とテスト
アプリケーションを再起動します。
ブラウザを開き、いずれかの投稿の詳細ページに移動します。コメントを見つけて、その横にある「返信」ボタンをクリックします。
コメントの直下にコメントフォームが表示されるのがわかります。

コンテンツを入力して送信します。ページがリフレッシュされると、返信が親コメントの下にインデントされて表示されます。

返信に返信を続けることができ、複数の会話レベルを作成できます。
これで、完全なコメント返信システムが完成しました。