Django TypeError: el objeto ‘RelatedManager’ no es iterable

2 minutos de lectura

avatar de usuario
megido

Tengo estos modelos de 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

digamos ese bloque b1 tiene el g1 grupo. Por su nombre quiero obtener todos los bloques del grupo g1. Escribí esta función recursiva:

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
    

Pero b1.group.block_set devuelve un Gerente relacionado objeto, que no es iterable.

¿Qué estoy haciendo mal y cómo puedo solucionarlo?

Prueba esto:

block in group.block_set.all()

  • ¿Alguien sabe por qué RelatedManager no está hecho para ser iterable? Hubiera esperado que fuera así…

    – pretzel rancio

    18 de noviembre de 2013 a las 0:33

  • Este comentario llega un poco tarde, pero el razonamiento es que puede usar los métodos de filtrado en el administrador para restringir la consulta antes de realizar una búsqueda en la base de datos.

    – ovalado

    20 de marzo de 2015 a las 14:45

  • @stalepretzel, porque funciona exactamente como un administrador de django estándar. No llama Model.objects e itera sobre él. Llamas a Model.objects.all() y luego iteras. Administrador de Django =/= conjunto de consultas de Django.

    – Saturnix

    18/11/2015 a las 22:40

  • y si lo está utilizando en una plantilla para bucle, puede hacer {% para objeto en objetos.otro_conjunto_de_objetos.todo %}

    – bcye

    28 de diciembre de 2019 a las 14:26

  • @stalepretzel … especialmente porque se llama “blocks_SET” y no “blocks_relatedmanager”. O “blocks_set_relatedmanager”.

    – Garras

    21 oct 2020 a las 10:48

úsalo como un Manager. Si quieres todos los objetos entonces llama al all() método.

avatar de usuario
ka

tiene que usar .all() con el nombre relacionado o el nombre del modelo childModel_set.

en vistas.py uso:

for item in object.relatedname.all():
    do something ......

en plantillas html uso:

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

¿Ha sido útil esta solución?