テンプレートフィルタって便利ですよね。
Djangoの標準では様々なフィルタが用意されています。
自作の処理でも、テンプレートフィルタのように、
Djangoテンプレートのコンテキスト出力時にメソッドを挟み込めたら・・・と考えて調べていたのですが・・・
テンプレートフィルタは簡単に自作できることがわかりました!
早速その方法について記述していきます。
templatetagsディレクトリを作成する
・アプリケーションディレクトリと同じ階層に作成します
・__init__.pyを作成し、パッケージ化する必要があります
ディレクトリ構造としては、下記のようになります。
ROOT `-- project_dir | |--project_name_dir | |--app_dir | |--templatetags | | | |--__init__.py | `
templatetagsディレクトリの中に任意の名前で、pythonソースを作成する
・今回はmy_filter.pyとしました
ROOT `-- project_dir | |--project_name_dir | |--app_dir | |--templatetags | | | |--__init__.py | |-- my_filter.py `
フィルタの処理を書き、Djangoテンプレートから使えるようにする
引数で受け取ったキーのモデルデータが存在するかどうかを調べるフィルタです。
存在する場合はTrue, 存在しない場合はFalseを返す
# coding: utf-8 from django.template.defaultfilters import register """ カスタムテンプレートフィルター """ # register.filterデコレータ # register.filter('is_any_data_exists', is_any_data_exists')でも可 @register.filter def is_any_data_exists(obj, pk): obj_list = obj.any_manytomany_field.filter(id=pk) if obj_list: return True else: return False
テンプレートから利用する
targetのmany_to_many_fieldに、
any_obj_pkのデータがあればTrue、なければFalseを返す
【具体例】 -------------------------------- ユーザ <- 既読一覧 -> 文書 -------------------------------- ・文書(target)に対して、該当ユーザー(any_obj_pk)の既読データがあるかないかを確認する ⇒データがあれば、既読 ⇒なければ未読
{% comment %}自作したフィルタを含むパッケージ名を指定{% endcomment %} {% load my_filter %} {% for target in target_list %} <tr> <td> {% if not target|is_any_data_exists:any_obj_pk %} <small>未読</small> {% endif %} <a target="_blank" href="{% url 'project:any_view_name' obj_id=obj.id %}">{{ target.title }}</a> </td> </tr> {% endfor %}
別の画面で、同様のテンプレート処理を行いたい場合にすごく便利ですね。