Python 代码在 Jinja 模板中的工作方式不相似
Python code not working similar in Jinja Template
我的程序有以下列表:
- 模块 - parent 列表
- 子模块 - parent 列表的 children
subtotal - 告诉在模块
之后应该打印多少个子模块
子内容 - children 个子模块
- contenttotal - 告诉在 sub-module
之后应该打印多少 sub-contents
module = [{'moduletitle': 'Parent Module 1', 'position': '1'}, {'moduletitle': 'Parent Module 2', 'position': '2'}, {'moduletitle': 'Parent Module 3', 'position': '3'}]
submodule = [{'moduletitle': 'sub module 11', 'position': '1'}, {'moduletitle': 'sub module 22', 'position': '2'}, {'moduletitle': 'sub module 1', 'position': '1'}, {'moduletitle': 'sub module 2', 'position': '3'}]
subtotal = [2,2,0]
subcontent = [{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'}] contenttotal=[0,0,1,0]
i1=0
i2=0
m=0
n=0
for i in range(0,len(module)):
print module[i]['moduletitle']
for j in range(0,subtotal[i1]):
print "\t",submodule[m]['moduletitle']
m=m+1
for k in range(0, contenttotal[i2]):
print "\t\t",subcontent[n]['content']
n=n+1
i2=i2+1
i1=i1+1
它产生了预期的结果:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 1
Dj.docx
sub module 2
Parent Module 3
现在,当我 运行 在像这样的 Jinja 模板中使用相同的代码时:
{% set i1=0 %}
{% set i2=0 %}
{% set m=0 %}
{% set n=0 %}
{% for i in range(0,moduledata | length ) %}
{{ moduledata[i]['moduletitle'] }} <br>
{% for j in range(0,subtotal[i1]) %}
{{ subparent[m]['moduletitle'] }}<br>
{% set m=m+1 %}
{% for k in range(0, subtotalcontent[i2]) %}
{{ subcontent[n]['content'] }}<br>
{% set n=n+1 %}
{% endfor %}
{% set i2=i2+1 %}
{% endfor %}
{% set i1=i1+1 %}
{%endfor%}
注意:我已将 Jinja 模板中的列表重命名为:
- 模块数据
- 子parent
- 小计
- 子内容
- 小计内容
在我 运行 之后,这里的相同代码是我收到的输出:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 11
sub module 22
Parent Module 3
为了确保在将数据发送到模板时我没有犯任何错误,我尝试在控制台上打印它们,这是我得到的结果:
[{'moduletitle': 'Parent Module 1', 'position': '1'}, {'moduletitle': 'Parent Module 2', 'position': '2'}, {'moduletitle': 'Parent Module 3', 'position': '3'}]
[{'moduletitle': 'sub module 11', 'position': '1'}, {'moduletitle': 'sub module 22', 'position': '2'}, {'moduletitle': 'sub module 1', 'position': '1'}, {'moduletitle': 'sub module 2', 'position': '3'}]
[2,2,0]
[{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'}]
[0,0,1,0]
因此两个程序具有相同的数据,但输出不同。
我同意 Martijn 所说的,如果你使用适当的嵌套数据结构,那么迭代它就会变得容易得多,python 与 jinja 语义不再那么重要。
以下是如何将所有列表转换为适当的嵌套结构的示例:
import pprint
modules = [
{'moduletitle': 'Parent Module 1', 'position': '1'},
{'moduletitle': 'Parent Module 2', 'position': '2'},
{'moduletitle': 'Parent Module 3', 'position': '3'},
]
submodules = [
{'moduletitle': 'sub module 11', 'position': '1'},
{'moduletitle': 'sub module 22', 'position': '2'},
{'moduletitle': 'sub module 1', 'position': '1'},
{'moduletitle': 'sub module 2', 'position': '3'},
]
subtotal = [2, 2, 0]
subcontent = [
{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'},
]
contenttotal = [0, 0, 1, 0]
###
#first, nest the "subcontent" items in the "submodule" items
subcontent_iter = iter(subcontent)
for sub, num_content_items in zip(submodules, contenttotal):
tmp = []
for i in range(num_content_items):
tmp.append(next(subcontent_iter))
sub['content'] = tmp
#then, nest the "submodule" items under the "module" items
submodule_iter = iter(submodules)
for (module, num_submodules) in zip(modules, subtotal):
tmp = []
for i in range(num_submodules):
tmp.append(next(submodule_iter))
module['submodules'] = tmp
pprint.pprint(modules)
并且输出:
[{'moduletitle': 'Parent Module 1',
'position': '1',
'submodules': [{'content': [],
'moduletitle': 'sub module 11',
'position': '1'},
{'content': [],
'moduletitle': 'sub module 22',
'position': '2'}]},
{'moduletitle': 'Parent Module 2',
'position': '2',
'submodules': [{'content': [{'content': 'Dj.docx',
'contenttitle': 'test content',
'contenttype': 'Pdf/Doc',
'coursemoduleid': 55341,
'position': '10'}],
'moduletitle': 'sub module 1',
'position': '1'},
{'content': [],
'moduletitle': 'sub module 2',
'position': '3'}]},
{'moduletitle': 'Parent Module 3', 'position': '3', 'submodules': []}]
看看这个数据结构现在看起来与您想要的输出有何相似之处?它遵循相同的模块嵌套模式 -> 子模块 -> 内容。
迭代现在变得小菜一碟,只需嵌套三个循环并每次迭代当前级别的子级,不再需要跟踪那么多索引:
for module in modules:
print module['moduletitle']
for submodule in module['submodules']:
print " ", submodule['moduletitle']
for content in submodule['content']:
print " ", content['content']
输出:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 1
Dj.docx
sub module 2
Parent Module 3
这个更简单的迭代应该在 jinja 中工作得很好。
IMO 如果您在 jinja 代码中加入如此多的逻辑,您更有可能 运行 遇到问题。对于这种数据操作,我更喜欢纯 python 代码,并且只会使用 jinja 来对数据进行一些轻量级的表示。与 jinja 相比,纯 python 代码更易于编写、调试和测试。
我的程序有以下列表:
- 模块 - parent 列表
- 子模块 - parent 列表的 children
subtotal - 告诉在模块
之后应该打印多少个子模块
子内容 - children 个子模块
- contenttotal - 告诉在 sub-module 之后应该打印多少 sub-contents
module = [{'moduletitle': 'Parent Module 1', 'position': '1'}, {'moduletitle': 'Parent Module 2', 'position': '2'}, {'moduletitle': 'Parent Module 3', 'position': '3'}]
submodule = [{'moduletitle': 'sub module 11', 'position': '1'}, {'moduletitle': 'sub module 22', 'position': '2'}, {'moduletitle': 'sub module 1', 'position': '1'}, {'moduletitle': 'sub module 2', 'position': '3'}]
subtotal = [2,2,0]
subcontent = [{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'}] contenttotal=[0,0,1,0]
i1=0
i2=0
m=0
n=0
for i in range(0,len(module)):
print module[i]['moduletitle']
for j in range(0,subtotal[i1]):
print "\t",submodule[m]['moduletitle']
m=m+1
for k in range(0, contenttotal[i2]):
print "\t\t",subcontent[n]['content']
n=n+1
i2=i2+1
i1=i1+1
它产生了预期的结果:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 1
Dj.docx
sub module 2
Parent Module 3
现在,当我 运行 在像这样的 Jinja 模板中使用相同的代码时:
{% set i1=0 %}
{% set i2=0 %}
{% set m=0 %}
{% set n=0 %}
{% for i in range(0,moduledata | length ) %}
{{ moduledata[i]['moduletitle'] }} <br>
{% for j in range(0,subtotal[i1]) %}
{{ subparent[m]['moduletitle'] }}<br>
{% set m=m+1 %}
{% for k in range(0, subtotalcontent[i2]) %}
{{ subcontent[n]['content'] }}<br>
{% set n=n+1 %}
{% endfor %}
{% set i2=i2+1 %}
{% endfor %}
{% set i1=i1+1 %}
{%endfor%}
注意:我已将 Jinja 模板中的列表重命名为:
- 模块数据
- 子parent
- 小计
- 子内容
- 小计内容
在我 运行 之后,这里的相同代码是我收到的输出:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 11
sub module 22
Parent Module 3
为了确保在将数据发送到模板时我没有犯任何错误,我尝试在控制台上打印它们,这是我得到的结果:
[{'moduletitle': 'Parent Module 1', 'position': '1'}, {'moduletitle': 'Parent Module 2', 'position': '2'}, {'moduletitle': 'Parent Module 3', 'position': '3'}]
[{'moduletitle': 'sub module 11', 'position': '1'}, {'moduletitle': 'sub module 22', 'position': '2'}, {'moduletitle': 'sub module 1', 'position': '1'}, {'moduletitle': 'sub module 2', 'position': '3'}]
[2,2,0]
[{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'}]
[0,0,1,0]
因此两个程序具有相同的数据,但输出不同。
我同意 Martijn 所说的,如果你使用适当的嵌套数据结构,那么迭代它就会变得容易得多,python 与 jinja 语义不再那么重要。
以下是如何将所有列表转换为适当的嵌套结构的示例:
import pprint
modules = [
{'moduletitle': 'Parent Module 1', 'position': '1'},
{'moduletitle': 'Parent Module 2', 'position': '2'},
{'moduletitle': 'Parent Module 3', 'position': '3'},
]
submodules = [
{'moduletitle': 'sub module 11', 'position': '1'},
{'moduletitle': 'sub module 22', 'position': '2'},
{'moduletitle': 'sub module 1', 'position': '1'},
{'moduletitle': 'sub module 2', 'position': '3'},
]
subtotal = [2, 2, 0]
subcontent = [
{'content': 'Dj.docx', 'position': '10', 'contenttype': 'Pdf/Doc', 'coursemoduleid': 55341, 'contenttitle': 'test content'},
]
contenttotal = [0, 0, 1, 0]
###
#first, nest the "subcontent" items in the "submodule" items
subcontent_iter = iter(subcontent)
for sub, num_content_items in zip(submodules, contenttotal):
tmp = []
for i in range(num_content_items):
tmp.append(next(subcontent_iter))
sub['content'] = tmp
#then, nest the "submodule" items under the "module" items
submodule_iter = iter(submodules)
for (module, num_submodules) in zip(modules, subtotal):
tmp = []
for i in range(num_submodules):
tmp.append(next(submodule_iter))
module['submodules'] = tmp
pprint.pprint(modules)
并且输出:
[{'moduletitle': 'Parent Module 1',
'position': '1',
'submodules': [{'content': [],
'moduletitle': 'sub module 11',
'position': '1'},
{'content': [],
'moduletitle': 'sub module 22',
'position': '2'}]},
{'moduletitle': 'Parent Module 2',
'position': '2',
'submodules': [{'content': [{'content': 'Dj.docx',
'contenttitle': 'test content',
'contenttype': 'Pdf/Doc',
'coursemoduleid': 55341,
'position': '10'}],
'moduletitle': 'sub module 1',
'position': '1'},
{'content': [],
'moduletitle': 'sub module 2',
'position': '3'}]},
{'moduletitle': 'Parent Module 3', 'position': '3', 'submodules': []}]
看看这个数据结构现在看起来与您想要的输出有何相似之处?它遵循相同的模块嵌套模式 -> 子模块 -> 内容。
迭代现在变得小菜一碟,只需嵌套三个循环并每次迭代当前级别的子级,不再需要跟踪那么多索引:
for module in modules:
print module['moduletitle']
for submodule in module['submodules']:
print " ", submodule['moduletitle']
for content in submodule['content']:
print " ", content['content']
输出:
Parent Module 1
sub module 11
sub module 22
Parent Module 2
sub module 1
Dj.docx
sub module 2
Parent Module 3
这个更简单的迭代应该在 jinja 中工作得很好。
IMO 如果您在 jinja 代码中加入如此多的逻辑,您更有可能 运行 遇到问题。对于这种数据操作,我更喜欢纯 python 代码,并且只会使用 jinja 来对数据进行一些轻量级的表示。与 jinja 相比,纯 python 代码更易于编写、调试和测试。