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 つのことを行う必要があります:
Model
を作成Form
を作成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 のコメントモジュールをインポートするモジュールを (間接的なインポートも含めて) インポートしていないか確認してください。
上記のプロセスで、大半のシチュエーションに対応できるはずです。より高度な使い方 として、さらに定義することのできるメソッドがあります。それらについては次の 章で説明します。
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 を返します。
Oct 26, 2017