superciccio14 superciccio14 - 5 months ago 43
Python Question

Django models: managing transactions when commit_manually is deprecated

I'm running Django 1.4.11. I overrode the

save()
method of a Django model in a way similar to the following code:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
# model definition

@transaction.commit_manually
def save(self, *args, **kwargs):
try:
super(self.__class__, self).save(*args, **kwargs)
foo() # do_other_things
except:
transaction.rollback()
raise
else:
transaction.commit()


When I run my code, sometimes I read this message in the Apache log:


RemovedInDjango18Warning: commit_manually is deprecated in favor of
set_autocommit.


How can I implement the same logic with set_autocommit?

Answer

The same logic would look like this:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    def save(self, *args, **kwargs):
        transaction.set_autocommit(False)
        try:
            super(MyModel, self).save(*args, **kwargs)
            foo() # do_other_things
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
        finally:
            transaction.set_autocommit(True)

However, this would be equivalent to using the atomic() decorator:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.atomic
    def save(self, *args, **kwargs):
        super(MyModel, self).save(*args, **kwargs)
        foo() # do_other_things

This will commit the transaction on a successful __exit__, and roll back in the case of an exception.