Fix select_for_update with nullable FK outer join error
Remove select_related('locked_by_user') from select_for_update query
to avoid PostgreSQL error "FOR UPDATE cannot be applied to the
nullable side of an outer join". Username is now fetched via lazy load.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -486,6 +486,7 @@ def add_showcase_kit_to_cart(request, kit_id):
|
||||
# Атомарная проверка и создание блокировки (предотвращает race condition)
|
||||
with transaction.atomic():
|
||||
# Блокируем строки резервов для этого комплекта на уровне БД
|
||||
# Примечание: нельзя использовать select_related с nullable FK при select_for_update
|
||||
reservations = Reservation.objects.select_for_update().filter(
|
||||
product_kit=kit,
|
||||
status='reserved'
|
||||
@@ -496,13 +497,15 @@ def add_showcase_kit_to_cart(request, kit_id):
|
||||
cart_lock_expires_at__gt=timezone.now()
|
||||
).exclude(
|
||||
locked_by_user=request.user
|
||||
).select_related('locked_by_user').first()
|
||||
).first()
|
||||
|
||||
if existing_lock:
|
||||
# Получаем username отдельным запросом (избегаем outer join с select_for_update)
|
||||
locked_by_username = existing_lock.locked_by_user.username if existing_lock.locked_by_user else 'другой кассир'
|
||||
time_left = (existing_lock.cart_lock_expires_at - timezone.now()).total_seconds() / 60
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': f'Этот букет уже в корзине кассира "{existing_lock.locked_by_user.username}". '
|
||||
'error': f'Этот букет уже в корзине кассира "{locked_by_username}". '
|
||||
f'Блокировка истечет через {int(time_left)} мин.'
|
||||
}, status=409) # 409 Conflict
|
||||
|
||||
|
||||
Reference in New Issue
Block a user