Django - Rollback save with transaction atomic

Gocht picture Gocht · Jan 11, 2016 · Viewed 52.6k times · Source

I am trying to create a view where I save an object but I'd like to undo that save if some exception is raised. This is what I tried:

class MyView(View):

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        try:
            some_object = SomeModel(...)
            some_object.save()

            if something:
                raise exception.NotAcceptable()
                # When the workflow comes into this condition, I think the previous save should be undone
                # What am I missing?

        except exception.NotAcceptable, e:
            # do something

What am I doing wrong? even when the exception is raised some_object is still in Database.

Answer

jlucier picture jlucier · Jan 11, 2016

Atomicity Documentation

To summarize, @transaction.atomic will execute a transaction on the database if your view produces a response without errors. Because you're catching the exception yourself, it appears to Django that your view executed just fine.

If you catch the exception, you need to handle it yourself: Controlling Transactions

If you need to produce a proper json response in the event of failure:

from django.db import SomeError, transaction

def viewfunc(request):
    do_something()

    try:
        with transaction.atomic():
            thing_that_might_fail()
    except SomeError:
        handle_exception()

    render_response()