gpt4 book ai didi

django - 查询模板所需的变量?

转载 作者:行者123 更新时间:2023-12-04 00:43:19 24 4
gpt4 key购买 nike

我希望能够从文件(大概使用 django.template.loader.get_template(filename) )实例化模板,然后确定应该在它传递的任何上下文中定义的变量集。

我以为 Template 对象上会有一个方法,但似乎没有。

我阅读了文档,发现最接近的是:

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

这建议转到管理界面以查看与给定 View 关联的所有变量。

我不想通过管理界面,因为我想以编程方式执行此操作——我正在尝试编写测试。

我正在使用 Django 版本 (1, 0, 2, 'final', 0)

更新:

我尝试了 Synack 的答案,发现(用 filter_expression.var 替换 filter_expression.token,以获取没有标签的变量的实际名称等)它返回了在模板中本地定义的变量,但没有工作对于在它扩展的父级中定义的变量。

例如,假设我有两个文件中的模板:

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 cool\n\n I heart it.\n\n'

但我无法从中获取两个变量:
>>> v=toy.nodelist.get_nodes_by_type(VariableNode)
>>> for k in v: print k.filter_expression.var
...
block.super
verb

最佳答案

您可以直观地检查模板并观察该模板的节点列表中是否存在任何“变量节点”对象:

>>> 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 的存在。并返回到父模板并单独获取这些变量名称。然而,这开始看起来像一 jar 蠕虫。

例如,如果您要这样做:
>>> toy.nodelist.get_nodes_by_type((ExtendsNode, VariableNode))
[<ExtendsNode: extends "mysite/toyparent.html">, <Variable Node: block.super>, <Variable Node: verb>]

现在您已获得 ExtendsNodeVariableNode对象,它开始变得困惑。那我们怎么办?我们是否试图忽略任何 block从此类测试返回的变量?我不知道!!

无论如何,这就是您想要的信息,但我认为这不是一个实用的解决方案。我坚持认为可能还有更好的方法。可能值得研究一下您要解决的问题,看看是否还有其他方法可以采用。

关于django - 查询模板所需的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1843324/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com