Python 对django模板节点进行后处理,以便在渲染之前组合标记
在django 1.6+中呈现模板之前,我需要组合连续的自定义模板标记。标签可以是与选定的“兼容”标签列表相同或不同的标签 在调用Python 对django模板节点进行后处理,以便在渲染之前组合标记,python,django,templates,Python,Django,Templates,在django 1.6+中呈现模板之前,我需要组合连续的自定义模板标记。标签可以是与选定的“兼容”标签列表相同或不同的标签 在调用render(context)之前,我试图循环遍历模板nodelist。这个循环将合并兼容的连续节点,但是我无法解决如何在使用上下文呈现模板之前自动调用模板上的函数 我看过 1) 中间件-似乎没有人可以访问已编译的模板节点列表 2) 自定义模板类-中断快捷方式,如渲染和渲染到响应 3) 直接在视图中的模板上调用函数-与上述问题相同 你对如何实现这一目标有何想法 一点
render(context)
之前,我试图循环遍历模板nodelist
。这个循环将合并兼容的连续节点,但是我无法解决如何在使用上下文呈现模板之前自动调用模板上的函数
我看过
1) 中间件-似乎没有人可以访问已编译的模板节点列表2) 自定义模板类-中断快捷方式,如
渲染
和渲染到响应
3) 直接在视图中的模板上调用函数-与上述问题相同 你对如何实现这一目标有何想法
一点背景 基本思想是使用不同的模板标记“一起渲染”,例如,在一个简化示例中:
{% tag_one "1A" "1B" %}{% tag_two "2A" %}
而不是渲染为两个单独的块:
[ 1A 1B ][ 2A ]
这将渲染为单个标记块:
[ 1A 1B 2A ]
在标记的呈现函数后面有比这更多的逻辑,但与此无关…您可以使用此代码段:并定义一个删除“][
”或其中任何内容的代码段
示例(在模板标签
目录中的文件中):
用法(在您看来):
未经测试的替代方法:它不需要任何templatetag,但如果您希望避免附带影响(例如,弄乱javascript代码),则必须非常有选择性地进行替换。它与您的尝试类似,但在呈现后而不是之前进行操作 以这种方式修改视图:
from django.shortcuts import render
def index(request):
myresponse = render(request, 'index.html') # add your context object if you need it
return HttpResponse(myresponse.content.replace(' ][ ', '')) # you may eventually use regex or eventually even a full html parser (!) but please take performances in account :)
您可以在提供给模板标记的解析器中“向前看”。例如,下面使用parser.next_token()
检查接下来的几个TemplateNodes
以查看它们是否兼容
def my_tag(parser, token):
parse_me = [token]
# the following lines check if there are any additional nodes
# that we should combine and adds them to a list for processing
if parser.tokens:
while parser.tokens[0].token_type == 2 and parser.tokens[0].content[0:3] == 'my_':
parse_me.append(parser.next_token())
contents = ""
for tok in parse_me:
# apply some logic to combine the nodes
contents += tok.contents
return MyCustomNode(contents)
我的答案是否满足您的要求?我可以做些什么来改进它?谢谢furins-一个很好的功能性答案。我希望模板标记上有一些更轻的东西-即不需要任何额外的标记。我想知道我是否可以使用解析器“向前看”?在这种情况下,您可以在返回HTTPResponse之前对其进行解析和操作,但在我看来,这种方法将为您的服务器增加额外的工作。我编辑了我的答案,以更具体的形式为您提供另一种方法。我没有时间测试它,但它应该是您代码中的一个简单替换,因此如果您愿意,可以尝试E
from django.shortcuts import render
def index(request):
myresponse = render(request, 'index.html') # add your context object if you need it
return HttpResponse(myresponse.content.replace(' ][ ', '')) # you may eventually use regex or eventually even a full html parser (!) but please take performances in account :)
def my_tag(parser, token):
parse_me = [token]
# the following lines check if there are any additional nodes
# that we should combine and adds them to a list for processing
if parser.tokens:
while parser.tokens[0].token_type == 2 and parser.tokens[0].content[0:3] == 'my_':
parse_me.append(parser.next_token())
contents = ""
for tok in parse_me:
# apply some logic to combine the nodes
contents += tok.contents
return MyCustomNode(contents)