
前の記事「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入力フィールドの値として設定します。 - 同時に、フォーム全体を返信対象のコメントの直後に移動させ、フォームのタイトルを更新して、ユーザーに明確なコンテキストを提供します。
- 返信時には「返信をキャンセル」ボタンが表示されます。これをクリックすると、フォームがリセットされ、コメントセクションの最下部に戻されます。
実行とテスト
アプリケーションを再起動します。
ブラウザを開き、いずれかの投稿の詳細ページに移動します。コメントを見つけて、その横にある「返信」ボタンをクリックします。
コメントの直下にコメントフォームが表示されるのがわかります。

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

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