Una solución sencilla sería poner el contador y el usuario ganador en el modelo Game. Luego puede usar select_for_update
para bloquear el registro:
game = Game.objects.select_for_update().get(pk=gamepk)
if game.number + 1 == X
# he is a winner
game.winner = request.user
game.number = game.number + 1
game.save()
else:
# u might need to stop the game if a winner already decided
Como parte de la misma transacción, también puede registrar Player
s objetos para que también sepa quién hizo clic y rastree otra información, pero no ponga el número y el ganador allí. Para usar select_for_update
necesitas usar postgresql_psycopg2
backend.
Actualización: Dado que Django configuró la confirmación automática de forma predeterminada, debe envolver el código anterior en una transacción atómica. De django docs
Puede decorar su vista con @transaction.atomic
:
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()