How to disable transaction in Django Admin?
Asked Answered
V

1

2

I used @transaction.non_atomic_requests for the overridden save() in Person model as shown below:

# "store/models.py"

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

class Person(models.Model):
    name = models.CharField(max_length=30)
    
    @transaction.non_atomic_requests # Here
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

And, I also used @transaction.non_atomic_requests for the overridden save_model() in Person admin as shown below:

# "store/admin.py"

from django.contrib import admin
from .models import Person
from django.db import transaction

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

    @transaction.non_atomic_requests # Here
    def save_model(self, request, obj, form, change):
        obj.save()

But, when adding data as shown below:

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 On PostgreSQL, how to log queries with transaction queries such as "BEGIN" and "COMMIT":

enter image description here

And, when changing data as shown below:

enter image description here

Transaction is used as shown below:

enter image description here

And, when clicking Delete button of Change person as shown below:

enter image description here

Then clicking Yes, I'm sure button to delete data as shown below:

enter image description here

Transaction is used as shown below:

enter image description here

And, when selecting Delete selected persons and clicking Go button of Select person to change as shown below:

enter image description here

Then clicking Yes, I'm sure button to delete data as shown below:

enter image description here

Transaction is used as shown below:

enter image description here

So, how can I disable transaction in Django Admin?

Visitor answered 8/12, 2022 at 9:42 Comment(0)
V
0

First to disable transaction when adding and changing data, you need to override changeform_view() in Person admin as shown below:

# "store/admin.py"

from django.contrib import admin
from .models import Person
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 # Here
    def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
        return self._changeform_view(request, object_id, form_url, extra_context)

Because by default, changeform_view() has with transaction.atomic(...): to use transaction when adding and changing data as shown below:

class ModelAdmin(BaseModelAdmin):
    
    # ...
    
    @csrf_protect_m
    def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
        with transaction.atomic(using=router.db_for_write(self.model)): # Here
            return self._changeform_view(request, object_id, form_url, extra_context)

As a result, when adding data as shown below:

enter image description here

Transaction is not used as shown below:

enter image description here

And, when changing data as shown below:

enter image description here

Transaction is not used as shown below:

enter image description here

Next to disable transaction when clicking Delete button of Change person then clicking Yes, I'm sure button to delete data, you need to override delete_view() in Person admin as shown below:

# "store/admin.py"

from django.contrib import admin
from .models import Person
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 # Here
    def delete_view(self, request, object_id, extra_context=None):
        return self._delete_view(request, object_id, extra_context)

Because by default, delete_view() has with transaction.atomic(...): to use transaction when clicking Delete button of Change person then clicking Yes, I'm sure button to delete data as shown below:

class ModelAdmin(BaseModelAdmin):
    
    # ...
    
    @csrf_protect_m
    def delete_view(self, request, object_id, extra_context=None):
        with transaction.atomic(using=router.db_for_write(self.model)): # Here
            return super()._delete_view(request, object_id, extra_context)

As a result, when clicking Delete button of Change person as shown below:

enter image description here

Then clicking Yes, I'm sure button to delete data as shown below:

enter image description here

Transaction is not used as shown below:

enter image description here

Lastly, you don't need to disable transaction for Delete selected persons because by default transaction is not used for Django Admin Actions including Delete selected persons. *You can see my post explaining more about Django Admin Actions with non-transaction by default.

Visitor answered 8/12, 2022 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.