コメントフレームワークをカスタマイズする

revision-up-to:17812 (1.4)

もし組み込みのコメントフレームワークがニーズに合わない場合、コメントアプリ の振る舞いを拡張して独自のデータやロジックを加えることができます。 コメントフレームワークは組み込みのコメントモデル、組み込みのコメントフォーム、 そして各種のコメントビューを拡張できるように作られています。

カスタマイズは、まず設定 COMMENTS_APP から始めましょう。 COMMENTS_APP に、あなたが使用したい、独自の振る舞いを提供するアプリの 名前を設定してください。設定は INSTALLED_APPS で使う書式と同じ書式で 行い、またそのアプリは INSTALLED_APPS の一覧に入っている必要が あります。

たとえば、もし my_comment_app という名前のアプリを使いたければ、 設定ファイルは次のようなコードを含むことになるでしょう:

INSTALLED_APPS = [
    ...
    'my_comment_app',
    ...
]

COMMENTS_APP = 'my_comment_app'

COMMENTS_APP で名前を指定したアプリは、アプリの __init__.py でモジュールレベルの関数をいくつか定義することで独自の振る舞いを提供します。 これらの関数の完全な一覧 は以下に記載しますが、 まずは簡単な例から見ていきましょう。

カスタムコメントアプリの例

もっとも一般的なカスタマイズの一例は、組み込みコメントモデルが提供するフィールド を変更するものです。たとえば、コメントを許可しているあるサイトがコメント投稿者に コメントのタイトルを付けられるようにしたいとします。組み込みコメントモデルには、 タイトルとして使えるフィールドはありません。

この種のカスタマイズを行うには、 3 つのことを行う必要があります:

  1. “title” フィールドを追加したカスタムのコメント Model を作成
  1. “title” フィールドを追加したカスタムのコメント Form を作成
  1. いくつかの関数を独自の COMMENTS_APP で定義することで、 Django にこれらのオブジェクトを使うよう伝える

ということで、上の例を続けると、 my_custom_app ディレクトリの下に 典型的なアプリの構造を作ることになります:

my_custom_app/
    __init__.py
    models.py
    forms.py

models.py の中では CommentWithTitle モデルを定義します:

from django.db import models
from django.contrib.comments.models import Comment

class CommentWithTitle(Comment):
    title = models.CharField(max_length=300)

普通は Comment モデルから派生したコメントモデルを作るでしょう。しかし、 もし「Comment モデルのフィールドを、物理的に削除あるいは変更したいが、 テンプレートは書き換えたくない」という場合には、 BaseCommentAbstractModel から派生させることに挑戦しても良いかも しれません。

次に、独自のコメントフォームを forms.py の中に定義します。これは少し 厄介です。フォームを作成してそれを返すよう CommentForm.get_comment_model() をオーバーライドし、また独自の title フィールドを処理するよう CommentForm.get_comment_create_data() をオーバーライドする必要があります:

from django import forms
from django.contrib.comments.forms import CommentForm
from my_comment_app.models import CommentWithTitle

class CommentFormWithTitle(CommentForm):
    title = forms.CharField(max_length=300)

    def get_comment_model(self):
        # Use our custom comment model instead of the built-in one.
        return CommentWithTitle

    def get_comment_create_data(self):
        # Use the data of the superclass, and add in the title field
        data = super(CommentFormWithTitle, self).get_comment_create_data()
        data['title'] = self.cleaned_data['title']
        return data

Django は特定のカスタムコメントフォームを書きやすくする 2 つの「ヘルパー」 クラスを提供しています。詳細は django.contrib.comments.forms を参照してください。

最後に、作成したクラスを使うよう Django に指示する 2 つのメソッドを my_custom_app/__init__.py の中で定義します:

from my_comments_app.models import CommentWithTitle
from my_comments_app.forms import CommentFormWithTitle

def get_model():
    return CommentWithTitle

def get_form():
    return CommentFormWithTitle

Warning

コメントアプリの中で循環インポートを作らないよう気を付けてください。 もし定義した通りにコメントの設定が使われていないように感じたなら – たとえばコメントのモデレーションポリシーが適用されていないなど – 循環インポートの問題があるかもしれません。

もしコメントに関する説明できない振る舞いが現れたなら、独自のコメント アプリケーションが Django のコメントモジュールをインポートするモジュールを (間接的なインポートも含めて) インポートしていないか確認してください。

上記のプロセスで、大半のシチュエーションに対応できるはずです。より高度な使い方 として、さらに定義することのできるメソッドがあります。それらについては次の 章で説明します。

カスタムコメントアプリの API

django.contrib.comments アプリは以下のメソッドを定義しています。 すべてのカスタムコメントアプリは、そのうち少なくとも一つを定義する必要が あります。しかし、どのメソッドも省略可能です。

get_model()

コメントに使う Model クラスを返します。このモデル は、必要な核となるフィールド群を定義した django.contrib.comments.models.BaseCommentAbstractModel を継承した ものになるはずです。

デフォルトの実装では django.contrib.comments.models.Comment を返します。

get_form()

コメントモデルの作成、検証、保存に使いたい Form クラスを返します。カスタムコメントフォームは最初に与えられる追加の引数 target_object を受け入れるべきです。これは、そのコメントに結びつけら れることになるオブジェクトです。

デフォルトの実装では django.contrib.comments.forms.CommentForm を返します。

Note

デフォルトのコメントフォームはいくつもの押し付けがましくない スパム防止機能を搭載しています (コメントフォームに関する注意 を参照してください)。もし独自のフォームに置き換えるのであれば、 組み込みフォームのソースコードを読んでみて、似たような機能を 導入した方が良いかもしれません。

get_form_target()

コメントを POST する URL を返します。これはコメントフォームをレンダリング するときに <form action> 属性になるでしょう。

デフォルトの実装は post_comment() ビューを指すリバース解決した URL を返します。

Note

もしカスタムコメントモデル・フォームを提供するけれどもデフォルトの post_comment() ビューを使いたい場合、そのモデルとフォームが 特定の追加の属性とメソッドを持つ必要があることに気付く必要があります。 詳しくは post_comment() ビューのドキュメントを参照してください。

get_flag_url()

「このコメントをフラグする」ビューの URL を返します。

デフォルトの実装は django.contrib.comments.views.moderation.flag() ビューを指すリバース解決した URL を返します。

get_delete_url()

「このコメントを削除する」ビューの URL を返します。

デフォルトの実装は django.contrib.comments.views.moderation.delete() ビューを指すリバース解決した URL を返します。

get_approve_url()

「このコメントを承認する」ビューの URL を返します。

デフォルトの実装は django.contrib.comments.views.moderation.approve() ビューを指すリバース解決した URL を返します。