askvictor
askvictor

Reputation: 3819

Does form_valid on a CreateView in django roll back a save if an error occurs?

I have a CreateView for a ModelForm with a form_valid() method, which calls form.save() quite early on (so that I can get the object's ID), then goes on to do some other stuff (create some related objects, and send some emails).

def form_valid(self, form):
    context = self.get_context_data()
    preferences_formset = context['preferences_formset']
    if preferences_formset.is_valid():
        student = form.save()
        ...
        send_email_one()
        send_email_two()
        send_email_three()
        return HttpResponseRedirect(self.get_success_url())

I recently discovered that some of the later processing had some errors resulting in an unhandled exception in some cases when send_email_three is called. I can see from my logs that send_email_one and send_email_two are being called, and the exception occurs in send_email_three. However, when this has occurred, I can't find the objects in the DB. I was under the impression that form.save() should create and save the object in the DB - is this the case or does it roll back the save if the form_valid function errors out at a later point?

I'm using django 1.8.17

PS: Yes, I know I should have the emails in a deferred task; that will be implemented later.

Upvotes: 1

Views: 841

Answers (2)

user2390182
user2390182

Reputation: 73498

That depends on the ATOMIC_REQUESTS setting. Setting it to True will trigger the behaviour described in the docs:

Before calling a view function, Django starts a transaction. If the response is produced without problems, Django commits the transaction. If the view produces an exception, Django rolls back the transaction.

Upvotes: 2

Related Questions