2016-10-19 7 views
0

今日は私の開発の奇妙な問題に直面しました。私は非常に最小の例でそれを再現しました。これら2つのダミークラス(非Djangoのモデルのサブクラス)を見てください:Djangoのテンプレート:__call__という魔方法は、非モデルオブジェクトのレンダリングを壊すのはなぜですか?

class DummyClassA(object): 
    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return 'Dummy1 object called ' + self.name 


class DummyClassB(object): 
    """Same as ClassA, with the __call__ method added""" 
    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return 'Dummy2 object called ' + self.name 

    def __call__(self, *args, **kwargs): 
     return "bar" 

彼らは同じですが、2番目は、特殊な__call__()方法があります。

私は組み込みDjangoテンプレートエンジンを使用してビューにこれらの2つのオブジェクトのインスタンスを表示したい:

class MyView(TemplateView): 

    template_name = 'myapp/home.html' 

    def get_context_data(self, **kwargs): 
     ctx = super(MyView, self).get_context_data(**kwargs) 

     list1 = [ 
      DummyClassA(name="John"), 
      DummyClassA(name="Jack"), 
     ] 

     list2 = [ 
      DummyClassB(name="Albert"), 
      DummyClassB(name="Elmer"), 
     ] 

     ctx.update({ 
      'list1': list1, 
      'list2': list2, 
     }) 
     return ctx 

と対応するテンプレート:

<h1>Objects repr</h1> 
    <ul> 
     {% for element in list1 %} 
      <li>{{ element }}</li> 
     {% endfor %} 
    </ul> 
    <ul> 
     {% for element in list2 %} 
      <li>{{ element }}</li> 
     {% endfor %} 
    </ul> 

    <h1>Access members</h1> 
    <ul> 
     {% for element in list1 %} 
      <li>{{ element.name }}</li> 
     {% endfor %} 
    </ul> 
    <ul> 
     {% for element in list2 %} 
      <li>{{ element.name }}</li> 
     {% endfor %} 
    </ul> 

私はこの結果を得ます

html result

2番目のクラス({{ element }})のスタンス、__repr__()の代わりに__call__メソッドが実行され、クラスのメンバーにアクセスしたい場合は何も返しません。

__call__()を定義して、Djangoテンプレートエンジンがこれらのインスタンスを処理する方法を変更する理由を理解できません。私はこれがバグではなく、主に機能だと思っていますが、好奇心が強いのですが、なぜ__call__()がこのような場合に実行されるのですか?そして、なぜ私はelement.nameの値を2番目のリストに入れられないのですか?

答えて

1

これは、テンプレート言語が行うように設計されているためです。 As the docs state

[変数を参照する]結果の値が呼び出し可能な場合、引数なしで呼び出されます。呼び出しの結果はテンプレート値になります。

テンプレートの構文で括弧を使用することができないため、これがないと、テンプレートでメソッドを呼び出す方法がありません。

+0

ありがとうございました – Antwane

関連する問題