【问题标题】:Python code not working similar in Jinja TemplatePython 代码在 Jinja 模板中不起作用
【发布时间】:2015-08-07 07:30:00
【问题描述】:

我的程序有以下列表:

  • 模块 - 父列表
  • 子模块 - 父列表的子模块
  • 小计 - 告诉在模块之后应该打印多少子模块

  • subcontent - 子模块的子项

  • contenttotal - 告诉子模块之后应该打印多少子内容

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

所以两个程序的数据相同,但输出不同。

【问题讨论】:

  • 这是一种非常复杂的树建模方法。为什么不只使用嵌套结构?给module 中的每个模块字典一个children 键,它是适用子模块的列表等?
  • 另外,你为什么不直接迭代列表项而不是使用range

标签: python python-2.7 python-3.x flask jinja2


【解决方案1】:

我同意 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 代码更容易编写、调试和测试。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 2021-01-12
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多