Reputation: 3819
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
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
Reputation: 1633
You can use @transaction.atomic
decorator
https://docs.djangoproject.com/en/1.10/topics/db/transactions/#controlling-transactions-explicitly
Upvotes: 1