Django模板列表不可迭代?

时间:2014-08-11 11:33:37

标签: django list templates

使用Django的模板遇到一个奇怪的问题,并且是n00b我甚至不知道如何调试模板......

问题:类型list的变量在传递到模板时以某种方式停止为list

在我看来,我有一堆传递给模板的变量是列表的字典。这是代码,

查看

project_image_design = {}

for p in projects:    
    project_image_design[p.id] = []    
    images = UploadedImage.objects.filter(project=p, image_type=UploadedImage.DESIGN)

    for i in images:
        project_image_design[p.id].append(i)

这是上下文。我有项目,每个都包含图像。我创建了一个字典,其中键是项目ID,值是与该项目关联的图像列表。

但是,当我在模板中使用它时,出现问题,

TEMPLATE

{% for p in projects %}
    <div class="row">

        {% for list in project_image_design|get_item:p.id %}
            {% for i in list %} 
                <div class="col-md-2"><img src = "{% get_static_prefix %}media/{{ i.filename }}"></div>
            {% endfor %}
        {% endfor %}

    </div>
{% endfor %}

所以在模板中,我正在迭代项目,然后使用项目的id(p.id)来获取字典值,这是一个图像列表,然后迭代它。花哨的get_item标记只是通过不是直接变量的键来访问字典值的一种方式(参见:Django template how to look up a dictionary value with a variable)。

无论如何,我收到了这个错误:

TypeError at /designer/my_projects/
'UploadedImage' object is not iterable

此行发生错误:{% for i in list %},这是我在使用项目ID检索的图像列表中迭代的行。

这里发生了什么??

我在视图中通过pdb进行了双重检查,它全部检出。传递的变量确实是一个列表字典,我在所有单独的字典元素上放了一个type,它们都是列表(例如:type(project_image_design[1])将返回<class 'list'>)。

此外,目前,所有列表都是长度为1.我想知道模板类型可能会缩小大小为1的列表吗?这似乎是一件非常奇怪的事情,可能不是原因。

任何帮助将不胜感激。

另外,我如何以调试Python代码的方式调试模板?喜欢踩到东西?这甚至可能吗?

1 个答案:

答案 0 :(得分:3)

它还没有停止成为一个列表。但是你有两个嵌套for循环:你遍历从字典中获得的项目 - 令人困惑地调用每个项目list - 然后再次尝试迭代该“列表”中的项目。但内循环毫无意义:你应该做的很简单:

{% for i in project_image_design|get_item:p.id %}
    <div class="col-md-2"><img src = "{% get_static_prefix %}media/{{ i.filename }}"></div>
{% endfor %}

我还要指出你的视图逻辑过于复杂。它可以简化为:

for p in projects:    
    project_image_design[p.id] = UploadedImage.objects.filter(project=p, image_type=UploadedImage.DESIGN)

实际上它可以进一步简化:你根本不需要字典或get_item标签。相反,在Project上提供一个名为design_images的方法,它只返回该类型的图像:

def design_images(self):
    return self.uploadedimage_set.filter(image_type=UploadedImage.DESIGN)

并完全从视图中删除字典逻辑,现在您的模板可以是:

{% for p in projects %}
    <div class="row">

        {% for i in p.design_images %}
            <div class="col-md-2"><img src = "{% get_static_prefix %}media/{{ i.filename }}"></div>
        {% endfor %}
    </div>
{% endfor %}