2009-12-03 6 views
12

私はファイル(おそらくdjango.template.loader.get_template(filename)を使用して)からテンプレートをインスタンス化し、それが渡されるどんなコンテキストでも定義されるべき変数のセットを決定したいと思っています。必要な変数のテンプレートを照会しますか?

私は、Templateオブジェクトにメソッドがあると思っていましたが、存在しないようです。

私は、ドキュメントを読んで、私が見つけた最も近いが、このでした:

http://docs.djangoproject.com/en/1.0/topics/templates/#using-the-built-in-reference

特定のビューに関連付けられているすべての変数を参照するには、adminインタフェースに行く示唆しています。

私はこれをプログラムで行う必要があるため、管理インターフェイスを使用したくないです。テストを作成しようとしています。私は、Djangoのバージョン使用してい

(1、0、2、 'final' は、0)

更新:私はSYNACKの答えを試してみましたが、見つけ

(そのfilter_expressionでfilter_expression.tokenの交換で.var、タグなしの変数の実際の名前を取得するなど)、テンプレート内でローカルに定義されている変数を返しましたが、拡張する親に定義されている変数では機能しませんでした。

toyparent.html:

{%block base_results%} 
Django is {{adjective}} 
{%endblock base_results%} 

toychild.html:私は子テンプレートを読み込む

{% extends "toyparent.html" %} 

{%block base_results%} 
    {{block.super}} 
    I {{verb}} it. 
{%endblock base_results %} 

そして:

したがって、たとえば、私は2つのファイルにテンプレートがあるとし

>>> toy=django.template.loader.get_template('toychild.html') 
>>> toy.render(django.template.Context(dict(adjective='cool',verb='heart'))) 
u'\n \nDjango is cool\n\n I heart it.\n\n' 

をしかし、私は、それから2つの変数を取得することはできません:これは正しくレンダリング

>>> v=toy.nodelist.get_nodes_by_type(VariableNode) 
>>> for k in v: print k.filter_expression.var 
... 
block.super 
verb 

答えて

20

あなたが視覚的にテンプレートを検査し、いずれかの「変数ノード」オブジェクトの存在を観察することができますそのテンプレートのノードリストに:

>>> from django.template import Template, Context 
>>> t = Template("Django is {{ adjective }} and I {{ verb }} it.") 
>>> t.nodelist 
[<Text Node: 'Django is '>, <Variable Node: adjective>, <Text Node: ' and I '>, <Variable Node: verb>, <Text Node: ' it.'>] 

これらは直接の比較で使用するためにインポートすることができるクラスであるタイプVariableNode、です。任意のNodeインスタンスは、ノードリストに対して呼び出すことができるget_nodes_by_type()メソッドを持ちます。このメソッドは、そのタイプのすべてのノードをテンプレートとして返します。例:

>>> from django.template import VariableNode 
>>> varnodes = t.nodelist.get_nodes_by_type(VariableNode) 
>>> varnodes 
[<Variable Node: adjective>, <Variable Node: verb>] 

これで、テンプレートの変数の一覧が表示されます。これは、それぞれの変数の実際の名前を抽出するために、より一歩前進する必要があります。reprの名前で愚かな文字列スライストリックを実行する必要はありません。

自体は各VariableNodeためfilter_expression.tokenに格納された変数名:

>>> varnodes[0].filter_expression.token 
u'adjective' 

だから、単純なリストの内包は、テンプレートの変数名のすべての私たちを取得します:だから

>>> template_vars = [x.filter_expression.token for x in varnodes] 
>>> template_vars 
[u'adjective', u'verb'] 

、ありません一番簡単な解決法ですが、もっと良い方法があればそれについてはわかりません。

ボーナス: A機能!

from django.template import VariableNode 
def get_template_vars(t): 
    varnodes = t.nodelist.get_nodes_by_type(VariableNode) 
    return [x.filter_expression.token for x in varnodes] 

これはあまりにも複雑ではありません。

フォローアップの編集:親テンプレート

から変数を取得する(このフォローアップを更新し、質問からの情報を使用しています)。

これは、おもちゃテンプレートのノードリストが単一のExtendsNode(この場合)であるため、実際には複雑になります。

>>> toy.nodelist 
[<ExtendsNode: extends "mysite/toyparent.html">] 

大きなテンプレートでは、複数のExtendsNodeオブジェクトが存在すると思います。

>>> enode = toy.nodelist[0] 
>>> enode.parent_name 
u'mysite/toyparent.html' 
>>> parent = enode.get_parent(enode.parent_name) 
>>> parent 
<django.template.Template object at 0x101c43790> 
>>> parent.nodelist.get_nodes_by_type(VariableNode) 
[<Variable Node: adjective>] 

そして、親テンプレートから抽出されたあなたのadjective変数があります:あなたはExtendsNodeを検査し、それから、親テンプレートを抽出する場合はとにかく、あなたは親に私の元の例と同じように扱うことができます。

>>> from django.template.loader_tags import ExtendsNode 
>>> ext = toy.nodelist.get_nodes_by_type(ExtendsNode) 
>>> ext 
[<ExtendsNode: extends "mysite/toyparent.html">] 

それで、あなたはExtendsNodeの存在のためのテンプレートに対していくつかのテストを行うことができますし、親テンプレートに後方を歩くと、個別にそれらの変数名を取得します:ExtendsNodeに対してテストを実行するには、django.template.loader_tagsからクラスをインポートすることができます。しかし、これはワームの缶のように見え始めています。例えば

、あなたがこれを行うにした場合:

>>> toy.nodelist.get_nodes_by_type((ExtendsNode, VariableNode)) 
[<ExtendsNode: extends "mysite/toyparent.html">, <Variable Node: block.super>, <Variable Node: verb>] 

は今、あなたは ExtendsNodeVariableNodeオブジェクトを持っているとそれだけで混乱取得を開始します。私たちは何をしていますか?このようなテストから返された変数 blockを無視しようとしますか?知りません!!

いずれにしても、これは必要な情報ですが、実際の解決策ではないと思います。おそらくもっと良い方法があると私は主張している。あなたが解決しようとしていることを調べて、別のアプローチがあるかどうかを調べる価値があるかもしれません。

+0

ありがとうございます - これは近いですが、継承のために適切に動作していないようです - 上記の問題の説明を参照してください。 –

+1

ああ、そうです。私はテンプレート拡張を考慮していませんでした。私を突きつけて、私がそれを理解できるかどうかを見てみましょう。 – jathanism

+1

うわー、素晴らしい研究と情報。 +1 –

関連する問題