Django TypeError: 'RelatedManager'对象不可迭代

120

我有以下这些Django模型:

class Group(models.Model):
    name = models.CharField(max_length=100)
    parent_group = models.ManyToManyField("self", blank=True)
    
    def __unicode__(self):
        return self.name


class Block(models.Model):
    
    name = models.CharField(max_length=100)
    app = models.CharField(max_length=100)
    group = models.ForeignKey(Group)

    def __unicode__(self):
        return self.name

设想区块 b1 拥有 g1 组。通过名称,我想从组 g1 获取 所有区块 。 我编写了这个递归函数:

def get_blocks(group):
    
    def get_needed_blocks(group):
        for block in group.block_set:
            blocks.append(block)

        if group.parent_group is not None:
            get_needed_blocks(group.parent_group)

    blocks = []
    get_needed_blocks(group)
    return blocks
    

但是 b1.group.block_set 返回的是一个RelatedManager对象,它不可迭代。

我做错了什么,如何修复?

4个回答

234

试试这个:

block in group.block_set.all()

15
有人知道为什么 RelatedManager 没有设计成可迭代的吗?我本以为它应该是这样的... - stalepretzel
4
这条评论有些晚了,但它的论点是你可以在从数据库获取数据之前,在经理上使用过滤方法来限制查询。 - ovangle
10
@stalepretzel,因为它与标准的Django管理器完全相同。你不是调用Model.objects并对其进行迭代。你调用Model.objects.all()然后进行迭代。Django管理器 ≠ Django查询集。 (翻译说明:本文旨在将原文内容尽可能准确地翻译成中文,同时保留原文的语言风格和专业术语,以满足读者阅读理解的需求。) - Saturnix
1
如果您正在使用它在模板的循环中,您可以这样做:{% for object in objects.other_object_set.all %} - bcye
@stalepretzel...特别是因为它被称为“blocks_SET”,而不是“blocks_relatedmanager”或“blocks_set_relatedmanager”。 - Klaws

33

15

你需要使用相关名称或子模型名称加上.all()。

在views.py中使用:

for item in object.relatedname.all():
    do something ......
在HTML模板中使用:

 {% for item in object.relatedname.all %}
   do something ......
 {% endfor %}

谢谢您的回复,但是能否解释一下为什么这是机制以及它是如何工作的呢?我有点困惑,不知道加上或者去掉括号有什么区别。谢谢。 - Fatemeh Sangin

2
如果您在Django模板中遇到此错误,请尝试:
{% for block in group.block_set.all %}
{{ block }}
{% endfor %}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接