LoginSignup
4

More than 5 years have passed since last update.

Djangoでカスタムタグ(フィルタ)を複数のアプリで共有する

Last updated at Posted at 2018-11-02

TL;DR

Djangoでカスタムタグ・フィルタをcoreやbaseに作って複数のアプリで使えるようにしたいときは、
settings.pyTEMPLATES欄に追記する必要があるよ

環境

  • 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.pyTEMPLATES欄に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敗)

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4