Django admin: Turning off DB transactions

Question:

I noticed that by default, all updates in the django admin site are done as transactions.

I need to either:
– turn off transactions (globally or for a particular admin view)
– inside of a save() method of an entity being saved via the admin interface, commit the transaction

The reason is that I overrode the save() method, and am notifying an external, non-django system about the change that just took place. However, the external system does not see the update since django has still not committed the transaction.

Does anyone have any suggestions on how to accomplish this?

Asked By: Krystian Cybulski

||

Answers:

You can use commit_manually to get full control of a transaction in a particular view/function.

Answered By: Sergey Golovchenko

A better solution might be to investigate your database’s transaction-isolation setting, since that’s the real reason why the external process can’t “see” the update…

Answered By: James Bennett

Only for when changing(updating) data on Django Admin, you can turn off transaction by overriding changeform_view(). *You can also see my post explaining about how to turn off all transactions in Django Admin.

For example, there is Person() model below:

# "store/models.py"

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=30)

Then, you need to override changeform_view() as shown below. *object_id is None when adding data while object_id is not None when changing data:

# "store/admin.py"

from django.contrib import admin
from .models import Person
from django.db import transaction
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
 
csrf_protect_m = method_decorator(csrf_protect)

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):

    @csrf_protect_m
    def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
        if object_id is None:
            with transaction.atomic(using=router.db_for_write(self.model)):
                return self._changeform_view(request, object_id, form_url, extra_context)
        else:
            return self._changeform_view(request, object_id, form_url, extra_context)

Now, when adding data:

enter image description here

Transaction is used as shown below. *I use PostgreSQL and these logs below are the queries of PostgreSQL and you can check how to log PostgreSQL queries with transaction:

enter image description here

But, when changing data:

enter image description here

Transaction is not used as shown below:

enter image description here

If you don’t override changeform_view() as shown below:

# "store/admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    pass

Then, change data:

enter image description here

Transaction is used as shown below:

enter image description here

Answered By: Kai – Kazuya Ito