TL;DR
Djangoでカスタムタグ・フィルタをcoreやbaseに作って複数のアプリで使えるようにしたいときは、
settings.py
のTEMPLATES
欄に追記する必要があるよ
環境
- Python 3.7.0
- Django 2.1.2
概要
例えばこんなmodelがあったとする。
users/models.py
class User(models.Model):
sex = models.IntegerField('性別', choices=((1, '男性'), (2, '女性')))
この時、Templateの側で性別の男性``女性
を表示したいが、user.get_sex_display()
を使えないとき(性別ごとの集計結果とか)はカスタムタグなりフィルタなりを作ると思う。
だけど、性別の表示なんて他でも使いそうだから、baseに定義して他のアプリからも使えるようにしたい…というときにどうすればいいかという話。
結論
まず、base/templatetags
にカスタムフィルタを作る。
例えばこんな感じ
base/templatetags/utility.py
from django import template
register = template.Library()
@register.filter()
def display_sex(sex_num):
"""性別の番号を文字に変換する。"""
if sex_num == 1:
return '男性'
if sex_num == 2:
return '女性'
そのあと、setting.py
のTEMPLATES
欄にbase/templatetags/utility.py
への参照を追記する。
(libraries
がないときは追加する)
settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'libraries': {
'utility': 'base.templatetags.utility' # 追記
}
},
},
]
これで、全アプリのテンプレートから{% load utility %}
して、フィルタを適用すればOK。
html
{% load utility %}
{% block contents %}
{{ 1|display_sex }} <!-- "男性"と表示される -->
{% endblock %}
(ちなみに{% load 'utility' %}
(utilityを文字列にする)とエラーになるので注意。(1敗)
参考