/ /必要な変数のテンプレートを照会しますか? - django、変数、django-templates

テンプレートに必要な変数を問い合わせますか? - django、変数、django-templates

私はテンプレートをインスタンス化できるようにしたい(おそらくdjango.template.loader.get_template(filename)を使用して)ファイルから取得し、渡されるコンテキストに関係なく定義される変数のセットを決定します。

私は、Templateオブジェクトにメソッドがあると思ったが、そうではないようだ。

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

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

これは、管理インターフェースに行き、所与のビューに関連するすべての変数を見ることを示唆している。

これをプログラムで実行したいので、私は管理インターフェースを使いたくありません - 私はテストを書くことを試みています。

私はDjangoのバージョン(1、0、2、 "final"、0)を使用しています

更新しました:

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

たとえば、2つのファイルにテンプレートがあるとします。

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 %}

そして私は子テンプレートを読み込みます:

>>> toy=django.template.loader.get_template("toychild.html")

これは正しく表示されます:

>>> toy.render(django.template.Context(dict(adjective="cool",verb="heart")))
u"n    nDjango is coolnn    I heart it.nn"

しかし、私はそれから2つの変数を得ることはできません:

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

回答:

答えは№1の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 名前。

変数名自体は filter_expression.token それぞれ VariableNode

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

したがって、単純なリストの理解は、テンプレートのすべての変数名を取得します。

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

だから、最も簡単な解決法ではありませんが、もっと良い方法があれば私はそれについて知りません。

ボーナス: 機能!!

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 オブジェクト。とにかく、あなたが 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 からクラスをインポートすることができます django.template.loader_tags

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

だから、あなたはテンプレートに対していくつかのテストをすることができます。 ExtendsNode 親テンプレートに戻り、個々に変数名を取得します。しかし、これはワームの缶のように見え始めています。

たとえば、これを行う場合は次のようにします。

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

今、あなたは ExtendsNode そして VariableNode オブジェクトとそれはちょうど混乱し始めます。私たちは何をしていますか?私たちは何も無視しようとしますか? block そのようなテストから返された変数知りません!!

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