Jarek.D
Jarek.D

Reputation: 1294

maximum recursion depth error when saving

I'm trying to update some other items of the same Model after creating new item and based on id of newly created item. That is why I have to do it after save. But I'm getting following error:

maximum recursion depth exceeded

The item object seems to be valid and the for loop itself is not recursive and iterates through the item objects normally. Introducing save() raises the error. Obviuosly I don't seem to fully understand the inner workings of save() method. Appreciate any help.

The code:

class SimCardInTracker(models.Model):
    tracker = models.ForeignKey(Tracker)
    simcard = models.ForeignKey(SimCard)
    start = models.DateTimeField(auto_now_add=True, unique=True)
    end = models.DateTimeField(null=True, blank=True) 

    def __unicode__(self):
        return self.tracker.serial_no

    def save(self, *args, **kwargs):
        super(SimCardInTracker, self).save(*args, **kwargs)
        prev_items =  SimCardInTracker.objects.exclude(id = self.id).filter(tracker__id = self.tracker.id)
        for item in prev_items:
            item.end = datetime.datetime.now()
            item.save()

Upvotes: 1

Views: 274

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

To answer your question: when you save a SimCardInTracker instance, it try to call save on all other instances having the same tracker. Imagine you have instances A, B and C all related to tracker T. When you call A.save(), your prev_items will yields [B, C]. You then call B.save(). Here, prev_items will be [A, C], so you end up calling A.save(), etc... You don't have this problem using Queryset.update() because it doesn't call Model.save() at all.

Upvotes: 1

Jarek.D
Jarek.D

Reputation: 1294

I think I've found quite elegant solution for this:

def save(self, *args, **kwargs):
    super(SimCardInTracker, self).save(*args, **kwargs)
    prev_items =  SimCardInTracker.objects.exclude(id = self.id).filter(tracker__id = self.tracker.id).update(end = datetime.datetime.now())

Upvotes: 0

Related Questions