In PersonAdmin():
below, I overrode response_add() with select_for_update() so that write skew doesn't occur then only 2 persons can be added on Add person and overrode save_model() so that obj.save()
works only when changing a person on Change person:
# "store/admin.py"
from django.contrib import admin
from .models import Person
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
def response_add(self, request, obj, post_url_continue=None):
# Here
obj_count = super().get_queryset(request).select_for_update().all().count()
if obj_count < 2:
obj.save()
return super().response_add(request, obj, post_url_continue)
def save_model(self, request, obj, form, change):
last_part_of_path = request.path.split('/')[-2]
if last_part_of_path == "change":
obj.save() # Here
But, when adding a person on Add person as shown below:
SELECT
is run instead of SELECT FOR UPDATE
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":
So, how can I run SELECT FOR UPDATE
instead of SELECT
when adding a person on Add person?
select_for_update() doesn't work with count():
But, select_for_update() works with len() as shown below:
So, when adding a person on Add person as shown below:
SELECT FOR UPDATE
is run instead ofSELECT
as shown below: