/ / Dotaz na šablónu pre premenné, ktoré potrebuje? - django, premenné, django-šablóny

Dotazujte šablónu pre premenné, ktoré potrebuje? - django, premenné, django-šablóny

Rád by som mohol vytvoriť šablónuzo súboru (pravdepodobne pomocou súboru django.template.loader.get_template (názov súboru)) a potom určiť súbor premenných, ktoré by mali byť definované v akomkoľvek kontexte.

Myslel som, že na objekte šablóny bude existovať metóda, ale zdá sa, že to nie je.

Čítal som dokumenty a najbližšie, čo som zistil, bolo toto:

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

čo naznačuje, že sa do administrátorského rozhrania zobrazia všetky premenné priradené k danému zobrazeniu.

Nechcem prejsť rozhraním správcu, pretože to chcem robiť programovo - snažím sa napísať testy.

Používam verziu Django (1, 0, 2, "konečné", 0)

Aktualizované:

Pokúsil som sa odpoveď synack a zistil som, že (snahradiť filter_expression.token filter_expression.var, získať skutočný názov premennej bez značiek atď.) vrátil premenné, ktoré sú definované lokálne v šablóne, ale nefungovalo pre premenné, ktoré sú definované v nadradenej hlave predlžuje.

Predpokladajme napríklad, že mám šablóny v dvoch súboroch:

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

A načítať šablónu pre deti:

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

To sa správne robí:

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

Ale ja nemôžem dostať dve premenné z nej:

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

odpovede:

20 pre odpoveď č. 1

Môžete vizuálne prezrieť šablónu a pozorovať prítomnosť akýchkoľvek objektov "Variable Node" v nodelistke šablóny:

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

Tieto sú typu VariableNode, čo je trieda, ktorú možno priamo použiť na porovnávanie. akýkoľvek Node inštancia má a get_nodes_by_type() metódu, ktorú možno zavolať proti nodelistovi, ktorý vráti všetky uzly tohto typu pre šablónu. Príklad:

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

Teraz máte zoznam premenných pre šablónu. Toto bude potrebné urobiť ďalší krok, aby sme extrahovali skutočný názov každej premennej bez toho, aby sme na jej repr Mená.

Samotný názov premennej sa uloží do priečinka filter_expression.token pre každý VariableNode:

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

A tak jednoduché pochopenie zoznamu nám prináša všetky názvy premenných pre šablónu:

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

Takže nie najjednoduchšie riešenie, ale ak je lepší spôsob, ako to neviem.

bonus: Funkcia!

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]

Ok, nie je to tak zložité!

Následná úprava: Získanie premenných z nadradených šablón

(Toto sledovanie využíva informácie z aktualizovanej otázky).

To je miesto, kde sa skutočne zložité, pretože nodelist šablóny hračky je jeden ExtendsNode (v tomto prípade).

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

Predstavoval by som si, že v širších šablónach by mohlo byť viac ExtendsNode objektov. V každom prípade, ak skontrolujete ExtendsNode, a extrahovať rodičovskú šablónu z nej, môžete zaobchádzať s rodičom rovnako ako môj pôvodný príklad:

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

A je tu vaša adjective premenná extrahovaná z nadradenej šablóny. Ak chcete vykonať test proti ExtendsNode môžete triedy importovať z 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">]

Takže by ste mohli urobiť nejaké testy proti šablonám na prítomnosť ExtendsNode a prejdite späť do nadradenej šablóny a individuálne získate tieto názvy premenných. Zdá sa však, že sa to zdá ako plechovka červov.

Ak by ste to napríklad urobili:

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

Teraz máte ExtendsNode a VariableNode objekty a práve začína byť mätúce. Čo potom robíme? Pokúsime sa ignorovať akékoľvek block premenné vrátené z takýchto testov? Neviem!!

V každom prípade ide o informácie, ktoré ste chceli,ale nemyslím si, že je to praktické riešenie, ale trvám na tom, že je stále pravdepodobne lepšia cesta.Môže byť vhodné zvážiť to, čo sa snažíte vyriešiť a zistiť, či existuje iný prístup, ktorý by ste mohli prijať.