Django admin: Turning off DB transactions
Asked Answered
B

4

8

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?

Break answered 14/6, 2009 at 14:54 Comment(2)
Great question. This is a common source of a race condition in Django's admin, and can be an incredibly frustrating problem to track down if you're unaware of Django's use of transactions within views.Epsomite
We've had a lot of success with pypi.python.org/pypi/django-celery-transactions. What this does is make sure that the transaction running when the background task is initiated completes before the task is allowed to runSquire
C
5

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

Continuant answered 14/6, 2009 at 14:59 Comment(0)
H
0

How to globally deactivate transaction management

Hallelujah answered 14/6, 2009 at 14:58 Comment(0)
K
0

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...

Kirkkirkcaldy answered 14/6, 2009 at 23:33 Comment(0)
D
0

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

Disport answered 2/1, 2023 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.