0

I'm struggling on finding an efficient way to go through Django m2m relations.

My use is case :

  • I receive a string from a form and update the status of an element with this string.
  • If this element has children, I update their status with the same value.
  • If those children element have themselves children, then I update the status and goes through their children etc ..

My model m2m field is like : parent = models.ManyToManyField('self', blank=True, default=None, symmetrical=False, verbose_name="")

Currently I've written something like this :

if model == Ensemble:
    children = elem.ensemble_set.all()
    for child in children:
        update_elem_statut(child, statut)
        for en in child.ensemble_set.all():
            update_elem_statut(en, statut)
            if len(en.ensemble_set.all()):
                for en_child in en.ensemble_set.all():
                    update_elem_statut(en_child, statut)

But that's definitely not recursive. I would need to loop through every children until there are only children element. I've no idea what would be the most pythonish/djangoish way to do this.

Thanks in advance for any help.

May.D
  • 1,832
  • 1
  • 18
  • 34

1 Answers1

2

Easy way to do this is to add a method to your model that calls the same method on all of the current objects children

class Ensemble(models.Model):

    def update_status(self, status):
        self.status = status
        self.save()
        for child in self.ensemble_set.all():
            child.update_status(status)
Iain Shelvington
  • 31,030
  • 3
  • 31
  • 50
  • Why not but how would I call it recursively ? – May.D Sep 18 '17 at 14:30
  • The call `child.update_status(status)` actually makes it recursive. – olieidel Sep 18 '17 at 14:42
  • First of all, thanks that's working. However I dont get why it's working, I understand why the method is called on children element of an instance, but I dont understand why it's therefore called on each children. I'd really use a bit of clarification. Is it normal recursive/python/django behavior ? – May.D Sep 18 '17 at 15:11
  • Not sure what you're not understanding. This method calls the `update_status` method of all the current objects children - which calls the `update_status` method of all if its children - which calls the `update_status` method of all if ITS children and so on – Iain Shelvington Sep 18 '17 at 15:31
  • Is it thanks to the self parameter in the definition of the function ? Anyway thank you for your answer and explanations. – May.D Sep 18 '17 at 16:59