/ / Eine Vorlage für die benötigten Variablen abfragen? - Django, Variablen, Django-Vorlagen

Eine Vorlage für die benötigten Variablen abfragen? - Django, Variablen, Django-Vorlagen

Ich möchte eine Vorlage instanziieren könnenaus einer Datei (vermutlich mit der Datei django.template.loader.get_template (Dateiname)), und dann bestimmen Sie die Menge der Variablen, die in welchem ​​Kontext auch immer übergeben werden soll.

Ich dachte, es würde eine Methode für das Template-Objekt geben, aber das scheint es nicht zu geben.

Ich las die Dokumente, und die nächste, die ich fand, war diese:

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

Dies schlägt vor, zur Admin-Schnittstelle zu gehen, um alle Variablen zu sehen, die mit einer bestimmten Ansicht verknüpft sind.

Ich möchte nicht über die Admin-Oberfläche gehen, weil ich das programmatisch machen möchte - ich versuche Tests zu schreiben.

Ich benutze Django Version (1, 0, 2, "final", 0)

Aktualisiert:

Ich habe Synacks Antwort versucht und festgestellt, dass (mit derErsetzen von filter_expression.token durch filter_expression.var, um den tatsächlichen Namen der Variablen ohne Tags zu erhalten usw.) Es wurden die Variablen zurückgegeben, die lokal in der Vorlage definiert sind, aber nicht für Variablen, die in der übergeordneten Klasse definiert sind erweitert.

Nehmen wir zum Beispiel an, ich habe Vorlagen in zwei Dateien:

spielzeugparent.html:

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

spielzeugkind.html:

{% extends "toyparent.html" %}

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

Und ich lade die Kindvorlage:

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

Dies macht richtig:

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

Aber ich kann die zwei Variablen nicht daraus erhalten:

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

Antworten:

20 für die Antwort № 1

Sie können eine Vorlage visuell überprüfen und das Vorhandensein von "Variablenknoten" -Objekten in der Nodeliste dieser Vorlage beobachten:

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

Diese sind von der Art VariableNodeDies ist eine Klasse, die direkt zur Verwendung in Vergleichen importiert werden kann. Irgendein Node Instanz hat a get_nodes_by_type() Methode, die gegen eine Nodelist aufgerufen werden kann, die alle Knoten dieses Typs für die Vorlage zurückgibt. Beispiel:

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

So, jetzt haben Sie eine Liste der Variablen für die Vorlage. Dies muss einen Schritt weiter gehen, um den tatsächlichen Namen jeder Variablen zu extrahieren, ohne dumme String-Slicing-Tricks zu machen repr Namen.

Der Variablenname selbst wird in gespeichert filter_expression.token für jede VariableNode:

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

Und so erhält uns ein einfaches Listenverständnis alle Variablennamen für die Vorlage:

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

Also, nicht die einfachste Lösung, aber wenn es einen besseren Weg gibt, weiß ich nichts darüber.

Bonus: Eine Funktion!!

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, es ist doch nicht so komplex!

Follow-up Edit: Abrufen von Variablen aus übergeordneten Vorlagen

(Dieses Follow-up verwendet die Informationen aus der aktualisierten Frage).

Dies ist, wo es tatsächlich komplex wird, weil die Nodelist der Spielzeugvorlage eine einzige ist ExtendsNode (in diesem Fall).

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

Ich könnte mir vorstellen, dass es in größeren Vorlagen mehrere geben könnte ExtendsNode Objekte. Wie auch immer, wenn Sie die ExtendsNodeund extrahieren Sie die übergeordnete Vorlage daraus. Sie können die übergeordnete Vorlage wie mein ursprüngliches Beispiel behandeln:

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

Und da ist dein adjective Variable, die aus der übergeordneten Vorlage extrahiert wurde. Einen Test gegen einen durchführen ExtendsNode Sie können die Klasse aus importieren 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">]

So könnten Sie einige Tests gegen Vorlagen für das Vorhandensein eines ExtendsNode und gehen Sie rückwärts zur Elternvorlage und erhalten Sie diese Variablennamen einzeln. Dies scheint jedoch wie eine Dose Würmer zu sein.

Zum Beispiel, wenn Sie dies tun würden:

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

Jetzt hast du die ExtendsNode und VariableNode Objekte und es beginnt nur verwirrend zu werden. Was machen wir dann? Versuchen wir, irgendwelche zu ignorieren block Variablen, die von solchen Tests zurückgegeben werden? Ich weiß es nicht!!

In jedem Fall, das ist die Information, die Sie wollten,Aber ich glaube nicht, dass dies eine praktische Lösung ist. Ich bestehe darauf, dass es immer noch einen besseren Weg gibt. Es könnte sich lohnen, zu untersuchen, was Sie zu lösen versuchen, und zu sehen, ob es noch einen anderen Weg gibt.