Как выполнить "SELECT FOR UPDATE" для стандартного "Delete selected" в Django Admin Actions?

У меня есть Person модель , как показано ниже:

# "store/models.py"

from django.db import models

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

А это Person админ ниже:

# "store/admin.py"

from django.contrib import admin
from .models import Person

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

Затем, нажав Go, перейдите к удалению выбранных лиц, как показано ниже:

enter image description here

Затем, нажав Да, я уверен для удаления выбранных лиц:

enter image description here

В транзакции выполняется только DELETE запрос, как показано ниже:

enter image description here

Теперь, как я могу запустить SELECT FOR UPDATE для стандартного "Delete selected" в Django Admin Actions?

Вам необходимо переопределить delete_queryset() с помощью raw queries и @transaction.atomic, как показано ниже, чтобы выполнить SELECT FOR UPDATE для стандартного "Delete selected" в Django Admin Actions:

# "store/admin.py"

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

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

    @transaction.atomic # Here
    def delete_queryset(self, request, queryset):
        ids = ()
        
        if len(queryset) > 1:
            for obj in queryset:
                ids += (obj.id,)
            ids = str(ids)
        else:
            ids = "(" + str(queryset[0].id) + ")"

        with connection.cursor() as cursor: # Here
            query = "SELECT * FROM store_person WHERE id IN " + ids + " FOR UPDATE"
            cursor.execute(query)
            query = "DELETE FROM store_person WHERE id IN " + ids
            cursor.execute(query)

Затем, нажав Go, перейдите к удалению выбранных лиц, как показано ниже:

enter image description here

Затем, нажав Да, я уверен для удаления выбранных лиц:

enter image description here

SELECT FOR UPDATE запрос и DELETE запрос выполняются в транзакции, как показано ниже:

enter image description here

Кроме того, вы можете проверить код по умолчанию delete_queryset(), который не переопределен, как показано ниже:

class ModelAdmin(BaseModelAdmin):
    
    # ...
    
    def delete_queryset(self, request, queryset):
        """Given a queryset, delete it from the database."""
        queryset.delete()
Вернуться на верх