【问题标题】:How to run "SELECT FOR UPDATE" for the default "Delete selected" in Django Admin Actions?如何在 Django 管理操作中为默认的“删除所选内容”运行“选择更新”?
【发布时间】:2022-12-20 08:35:35
【问题描述】:
我有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
然后,当点击走去删除选中的人物如下图:
然后,点击是,我确定删除所选人员:
仅有的DELETE查询在事务中运行如下图:
现在,我如何运行SELECT FOR UPDATE默认“删除选中”在Django 管理操作?
【问题讨论】:
标签:
python
python-3.x
django
django-admin-actions
select-for-update
【解决方案1】:
你需要覆盖delete_queryset()原始查询和@transaction.atomic如下所示运行SELECT FOR UPDATE默认“删除选中”在Django 管理操作:
# "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
cursor.execute("SELECT * FROM store_person WHERE id IN " + ids + " FOR UPDATE")
cursor.execute("DELETE FROM store_person WHERE id IN " + ids)
然后,当点击走去删除选中的人物如下图:
然后,点击是,我确定删除所选人员:
SELECT FOR UPDATE查询和DELETE查询在事务中运行,如下所示:
此外,您可以检查未被覆盖的默认代码delete_queryset(),如下所示:
class ModelAdmin(BaseModelAdmin):
# ...
def delete_queryset(self, request, queryset):
"""Given a queryset, delete it from the database."""
queryset.delete()