TypeError: об'єкт 'RelatedManager' не піддається ітерації


85

Джанго

У мене є наступні моделі:

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 , який не можна повторити.

Що робити? Що не так?

Відповіді:


175

Спробуйте це:

block in group.block_set.all()

9
Хтось знає, чому RelatedManager не створено таким, щоб бути ітерабельним? Я би очікував, що це буде так ...
stalepretzel

2
Цей коментар трохи запізнився, але міркування полягає в тому, що ви можете використовувати методи фільтрації в диспетчері, щоб обмежити запит перед виконанням отримання до db.
овангл

8
@stalepretzel, оскільки він працює точно як стандартний менеджер django. Ви не викликаєте Model.objects і не перебираєте його. Ви викликаєте Model.objects.all (), а потім виконуєте ітерацію. Диспетчер Django = / = Набір запитів Django.
Сатурнікс

і якщо ви використовуєте його в шаблоні для циклу, ви можете зробити {% для об'єкта в objects.other_object_set.all%}
Брюс

@stalepretzel ... тим більше, що він називається "blocks_SET" - а не "block_relatedmanager". Або "block_set_relatedmanager".
Klaws

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.