/ / Запитване за шаблон за променливите, от които се нуждае? - django, променливи, django-шаблони

Заявете шаблон за променливите, от които се нуждаете? - django, променливи, django-шаблони

Бих искал да мога да създам шаблонот файл (вероятно с помощта на django.template.loader.get_template (име на файл)) и след това определете множеството от променливи, които трябва да бъдат дефинирани в какъвто и да е контекст.

Мислех, че ще има метод върху обекта на шаблона, но не изглежда.

Прочетох документите и най-близкото, което намерих, беше следното:

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

което предполага да отидете в администраторския интерфейс, за да видите всички променливи, свързани с даден изглед.

Не искам да мина през администраторския интерфейс, защото искам да направя това по програмиране - опитвам се да напиша тестове.

Използвам версията Django (1, 0, 2, "final", 0)

Обновено:

Опитах се да отговоря на сина си и установих, че (сзамяната на filter_expression.token с filter_expression.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 %}

И зареждам шаблона на детето:

>>> 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"

Но не мога да получа двете променливи от него:

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

Отговори:

20 за отговор № 1

Вие сте в състояние да визуализирате шаблон и да наблюдавате наличието на обекти "Variable Node" в номенклатурата на този шаблон:

>>> 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() метод, който може да бъде наречен срещу nodelist, който връща всички възли от този тип за шаблона. Пример:

>>> 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 променливи, върнати от такива тестове? Не знам!!

Във всеки случай, това е информацията, която искате,но не мисля, че това е практично решение.Надявам се, че все още има по-добър начин.Вие може би си заслужава да разгледате какво се опитвате да разрешите и да видите дали има друг подход, който можете да предприемете.