1
0

More than 3 years have passed since last update.

Djangoテンプレートで呼び出し可能な変数を呼び出させないようにする

Posted at

結論

オブジェクトにdo_not_call_in_templates = Trueを付与する

class SampleCallableClass:
    do_not_call_in_templates = True

    def __call__(self):
        pass

    def sample_method(self):
        pass
    sample_method.do_not_call_in_templates = True

概要

Djangoテンプレートでは、ある変数が呼び出し可能かどうかをまずチェックし、呼び出し可能であれば引数無しで呼び出します。

例えば、{{ Hoge.fuga }}において、Hogeが呼び出し可能である場合、これは{{ Hoge().fuga }}のように評価されます。

しかしながら、呼び出し可能なオブジェクトを呼び出さずにそのプロパティにアクセスしたいという場合があります。

例えばHogeが列挙型である場合は引数無しでの呼び出しHoge()が出来ずにエラーとなり、残りの要素.fugaは評価されず、最終的に空の文字列が出力されます。

こうした状況について、公式ドキュメントには以下のように記述されています。

Occasionally you may want to turn off this feature for other reasons, and tell the template system to leave a variable uncalled no matter what. To do so, set a do_not_call_in_templates attribute on the callable with the value True. The template system then will act as if your variable is not callable (allowing you to access attributes of the callable, for example).

https://docs.djangoproject.com/en/3.0/ref/templates/api/#variables-and-lookups

呼び出し可能オブジェクトにdo_not_call_in_templates = Trueを付与することで、呼び出し可能でないかのように振る舞わせることが出来るようになります。

余談

Django3.0で追加されたChoicesの実装を読んでいた際に、ChoicesMeta__new__メソッドにdo_not_call_in_templatesが使われているのを見つけて記事にしてみました。

1
0
0

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
1
0