revision-up-to: | 17812 (1.4) |
---|
Django には単純ながらカスタマイズ可能なコメントフレームワークが付属していま す。この組み込みのコメントフレームワークを使えば、任意のモデルにコメントを 付加できます。つまり、ブログエントリや写真、本、本の各章、その他あらゆるも のにコメントを付けられるのです。
Note
Django の古い (ドキュメント化されなかった) コメントフレームワークを使っ ていたのなら、アップグレードが必要です。 アップグレードガイド を参照してください。
comments
を使うには、以下のステップに従います:
INSTALLED_APPS
に 'django.contrib.comments'
を
インストールします。
manage.py syncdb
を実行して、コメントフレームワークのテーブルを
生成します。
コメントアプリケーションの URL をプロジェクトの urls.py
にマップ
します:
urlpatterns = patterns('',
...
(r'^comments/', include('django.contrib.comments.urls')),
...
)
コメントテンプレートタグ を使って、 コメント機能をテンプレートに埋め込みます。
コメントフレームワークの設定 も調べておきましょう。
コメントシステムは、主にテンプレートタグを使って操作します。テンプレートタ グを使えば、コメントをポストするためのフォームや、ポストされたコメントを埋 め込めます。
他のカスタムテンプレートタグライブラリと同様、使うには カスタムタグライブラリをロード しておかねばなりません:
{% load comments %}
タグライブラリをロードすれば、後で解説するテンプレートタグを使えるようにな ります。
Django のコメントは、全て何らかのオブジェクトに「結びついて (attached)」い ます。コメントは、任意の Django モデルのインスタンスに結びつけられます。 以下のタグを使うと、 2 種類の方法で、コメントを結びつけたいオブジェクトを指 定できます:
オブジェクトを直接参照する方法 – より一般的な方法です。たいていの場 合、コメントを結びつけたいオブジェクトはテンプレートコンテキストの中 に入っているはずです。そのオブジェクトを使います。
例えば、あるブログのエントリ表示ページに entry
という変数が入っ
ていて、エントリオブジェクトを表現しているなら、以下のようにして、
entry
に結び付いたコメントの数を表示できます:
{% get_comment_count for entry as comment_count %}.
オブジェクトをコンテンツタイプとオブジェクト id で指定する方法。何ら かの理由で、コメントを結び付ける対象のオブジェクトに直接アクセスでき ない場合に使います。
上のような例で、オブジェクトの id が 14
だと分かっていて、かつ対
象のオブジェクトにアクセスできないなら、以下のようにします:
{% get_comment_count for blog.entry 14 as comment_count %}
この例の blog.entry
は、アプリケーションラベルと (小文字にした)
モデルクラス名をつなげたものです。
コメントの一覧を表示するには、テンプレートタグ render_comment_list
または get_comment_list
を使用します。
あるオブジェクトへのコメントを一覧表示する一番簡単な方法は
render_comment_list
を使用する方法です:
{% render_comment_list for [object] %}
たとえば:
{% render_comment_list for event %}
これは comments/list.html
という名前のテンプレートを使ってコメントを
レンダリングします。このテンプレートのデフォルトバージョンは Django に標準で
含まれています。
あるオブジェクトへのコメントのリストを取得するには get_comment_list
を使います:
{% get_comment_list for [object] as [varname] %}
例を挙げましょう:
{% get_comment_list for event as comment_list %}
{% for comment in comment_list %}
...
{% endfor %}
これは Comment
オブジェクトのリストを
返します。詳細は コメントモデルのドキュメント を参照してください。
リリースノートを参照してください
特定のコメントへのパーマリンク (permalink) を提供するには、
get_comment_permalink
を使います:
{% get_comment_permalink comment_obj [format_string] %}
デフォルトでは URL の後ろに追加される名前付きアンカー (訳注: # に続けて記す フラグメント識別子) は、 ‘c82’ のように、 ‘c’ にコメント ID を続けたものに なります。この動作を変更したい場合、カスタム書式を指定することもできます:
{% get_comment_permalink comment "#c%(id)s-by-%(user_name)s"%}
この書式を指定する文字列は、 Python 標準の書式化用文字列です。有効なマップキー として、コメントオブジェクトの属性すべてが利用可能になっています。
独自にカスタムしたアンカーのパターンを指定するかどうかに関わらず、 テンプレートの適切な場所に対応した名前付きアンカーを配置する必要があります。
たとえば:
{% for comment in comment_list %}
<a name="c{{ comment.id }}"></a>
<a href="{% get_comment_permalink comment %}">
permalink for comment #{{ forloop.counter }}
</a>
...
{% endfor %}
Warning
Safari/Webkig にはリダイレクト後に名前付きアンカーが忘れられる既知のバグが あります。これが実際問題としてコメントに与える影響は、 Safari/webkig ブラウザは正しいページにたどり着くものの名前付きアンカーの位置にまで スクロールしてくれない、というものです。
オブジェクトに結びつけられたコメントの数を取得するには、
get_comment_count
を使います:
{% get_comment_count for [object] as [varname] %}
例を挙げましょう:
{% get_comment_count for event as comment_count %}
<p>This event has {{ comment_count }} comments.</p>
ユーザがコメントを投稿できるようフォームを表示するには、
render_comment_form
や get_comment_form
を使います。
コメントフォームを表示する最も簡単な方法は、
render_comment_form
を使うやり方です:
{% render_comment_form for [object] %}
例を挙げましょう:
{% render_comment_form for event %}
このコードによって、Django に付属のデフォルトの comments/form.html
テン
プレートを使ってコメントフォームがレンダされます。
コメントフォームのルック&フィールを制御したければ、
get_comment_form
を使って フォームオブジェクト を取得し、テンプレート内で使います:
{% get_comment_form for [object] as [varname] %}
これで、フォームは以下のように書けます:
{% get_comment_form for event as form %}
<table>
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{{ form }}
<tr>
<td colspan="2">
<input type="submit" name="submit" value="Post">
<input type="submit" name="preview" value="Preview">
</td>
</tr>
</form>
</table>
このアプローチをとるときには、いくつか考慮すべき点があります。後述の コメントフォームに関する注意 をよく読んでく ださい。
上の例では、 comment_form_target
というもう一つのタグを使って、フォー
ムの action
属性を取得していたことに気づいたでしょうか。このタグは、常
にコメントフォームのポスト先として正しい URL を返します。コメントフォームを
使うときには、いつも以下のように書いてください:
<form action="{% comment_form_target %}" method="post">
コメントが投稿された後にリダイレクトする URL を指定したい場合、 next
という名前の非表示の input 要素をフォームに含めることができます。たとえば:
<input type="hidden" name="next" value="{% url my_comment_was_posted %}" />
コメントシステムの使っているフォームには、スパムを防ぐための重要な属性があ ります。これらの属性についてよく知っておきましょう:
フォームには、タイムスタンプやコメントを結び付ける対象のオブジェクト、 これらの情報を検証するための「セキュリティハッシュ(security hash)」な ど、いくつもの隠しフィールドが入っています。コメントスパム屋がよくや るように、これらのフィールドの値を改ざんしようとすると、コメントの投 稿に失敗します。
自作のコメントフォームを出力するときには、この隠しフィールドの値を変 更せずに渡してください。
タイムスタンプは、長時間再生攻撃が繰り返されるのを防ぐために使われま す。フォームのリクエストからコメントのポストまで長時間経っている場合、 フォームの提出は拒否されます。
コメントフォームには、「 ハニーポット (honeypot)」フィールドがあ ります。このフィールドはトラップです: このフィールドに何らかのデータ が入力されると、そのコメントはスパムであると見なされます (スパムプロ グラムは、有効なフォーム入力を偽装するために、全てのフィールドを自動 的に埋めようとするからです)。
デフォルトのフォームは、 CSS を使ってこのフォームを隠し、ラベルにも 警告の文字列を入れます。カスタムのテンプレートでコメントフォームを使 うときにも、同じようにしてください。
コメントアプリは Django に同梱されているより一般的な CSRF 対策の機能 に依存しています。そちらのドキュメントに記載されている通り、
CsrfViewMiddleware
を使うのがベストです。しかし、もしそれを使っていなければ、
CSRF トークンとクッキーを出力できるよう、コメントフォームを含むすべてのビューで
csrf_protect
デコレータを使う必要があります。
Oct 26, 2017