如何在Django Admin修改/删除数据时执行SELECT FOR UPDATE而非SELECT
在Django Admin中为修改和删除操作添加SELECT FOR UPDATE锁
默认情况下,Django Admin在加载对象进行修改或删除时,执行的是普通SELECT语句,不会添加行级锁。要实现这两个场景下都执行SELECT FOR UPDATE,只需重写Admin类的get_object方法,在获取对象时加上行级锁逻辑。
修改后的store/admin.py代码如下:
from django.contrib import admin from django.http import Http404 from .models import Person @admin.register(Person) class PersonAdmin(admin.ModelAdmin): def get_object(self, request, object_id, from_field=None): queryset = self.get_queryset(request) model = queryset.model field = model._meta.get_field(from_field or model._meta.pk.name) try: object_id = field.to_python(object_id) # 为查询添加行级锁,触发SELECT FOR UPDATE return queryset.select_for_update().get(**{field.name: object_id}) except (model.DoesNotExist, ValueError, TypeError): raise Http404(f"{model._meta.verbose_name} object with primary key {object_id!r} does not exist.")
说明
- Django Admin进入修改页面、执行删除操作时,都会调用
get_object方法获取目标对象,重写该方法就能统一控制对象查询的锁机制。 select_for_update()会让PostgreSQL执行SELECT ... FOR UPDATE语句,对查询到的行加排他锁,直到当前事务结束才释放,避免并发操作导致的数据不一致问题。- 该方法仅对支持行级锁的数据库生效(如PostgreSQL),完全匹配你的使用场景。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

