aalberti333
aalberti333

Reputation: 1229

Override save in Django causing infinite recursion error

(Django 2.0, Python 3.6, Django Rest Framework 3.8)

I'm trying to override Django's save() method to post multiple instances when a single instance is created. I have a loop that changes the unique_id which I have saved as a randomly generated string, and the datetime value which is updated through another function called onDay().

My thinking was, that if I changed the unique_id each time I looped around, Django would save the instance as a new instance in the database. But, I keep getting back an infinite recursion error when I run it though. When I checked it with pdb.set_trace(), everything does what it's supposed to until I hit the save() value in the for loop. Once that happens, I just get taken back to the line if self.recurrent_type == "WEEKLY":.

I've used super() in a similar way (without looping) to override the save() function for a separate model, and it worked as expected. I think there's just something I'm misunderstanding about the super() function.

Here is what I have so far:

Overriding save()

def save(self, *args, **kwargs):
        if not self.pk:  # if there is not yet a pk for it
            # import pdb; pdb.set_trace()
            if self.recurrent_type == "WEEKLY":
                LIST_OF_DAYS = self.days_if_recurring["days"]
                HOW_MANY_DAYS_FOR_ONE_WEEK = len(LIST_OF_DAYS)
                REPEATS = HOW_MANY_DAYS_FOR_ONE_WEEK * self.number_of_times_recurring
                RESET_COUNTER = 0
                for i in range(REPEATS):
                    self.id = ''.join(random.choices(string.ascii_letters, k=30))
                    self.calendarydays = onDay(self.calendarydays, LIST_OF_DAYS[RESET_COUNTER])
                    if RESET_COUNTER == HOW_MANY_DAYS_FOR_ONE_WEEK - 1:
                        RESET_COUNTER = 0
                    self.save()
            else:
                self.id = ''.join(random.choices(string.ascii_letters, k=30))
                self.save()
        return super(Bookings, self).save(*args, **kwargs)

onDay()

def onDay(date, day):  # this function finds next day of week, and skips ahead one week if today's time has already passed
    utc = pytz.UTC
    check_right_now = utc.localize(datetime.datetime.now())
    if check_right_now > date:
        forward_day = date + datetime.timedelta(days=(day - date.weekday() + 7) % 7) + datetime.timedelta(days=7)
    else:
        forward_day = date + datetime.timedelta(days=(day - date.weekday() + 7) % 7)
    return forward_day

As always, any help is greatly appreciated.

Upvotes: 4

Views: 1016

Answers (1)

Brian Destura
Brian Destura

Reputation: 12068

You should call super(Bookings, self).save(*args, **kwargs) instead of self.save(). The super save will call django's actual model save which is what you want. Calling self.save() will just call your overridden save which doesn't do anything in the database. But yeah what @AamirAdnan said should fix your problem.

Upvotes: 3

Related Questions