Django channels: обновление базы данных удаляет старые данные из той же сессии на сокете
Я создаю игру tic tac toe, в которую можно играть онлайн, но я хотел сохранить счетчик побед/поражений каждого пользователя, и я использую django 3.2, channels 3 и channels_presence с python 3.9
Я успешно собрал сокет и клиент, и теперь вы можете играть столько игр, сколько захотите... Я думаю
Проблема заключается в том, что счет, который я пытаюсь сохранить, сохраняется в базе данных, но после очередной игры счет возвращается к нулю
так, если два пользователя играют в комнате и пользователь 1 выиграл 2 игры, счет будет обновлен, тогда если другой пользователь выиграет игру, его счет будет равен 1, а счет пользователя 1 будет сброшен на ноль
Моя модель пользователя
class CustomUser(AbstractUser):
won_games = models.IntegerField(default=0)
lost_games = models.IntegerField(default=0)
draw_games = models.IntegerField(default=0)
def win(self):
self.won_games += 1
self.save()
def lose(self):
self.lost_games += 1
self.save()
def draw(self):
self.draw_games += 1
self.save()
Я поместил это в функцию receive в моем consumers.py
class GameConsumer(WebsocketConsumer):
#some code
def receive(self, text_data):
if text_data['type'] == 'completed':
self_channel = Presence.objects.get(channel_name=self.channel_name)
competitor = self_channel.room.presence_set.filter(
~Q(channel_name=self_channel)
).first().user
user = self.scope['user']
if competitor:
competitor.win()
if user.is_authenticated:
user.lose()
return
**Примечание: **Я полагаюсь на сообщение другого пользователя для подтверждения выигрыша, чтобы никто не мог послать фальшивые выигрыши на сокет
Я пытался удалить всех пользователей из базы данных, перенести базу данных, изменить способ изменения свойства won_games, как вы можете видеть, но проблема в том, что оно возвращается к умолчанию после проигрыша
Если вы можете помочь мне, вот полный исходный код https://github.com/ahmedyasserays/XO-online
Я исправил это, проблема была в части user = self.scope['user']
.
Как вы сейчас говорите, при инициировании соединения с потребителем в памяти создается новый экземпляр потребителя из вашего класса с некоторыми атрибутами, как это self.scope
обновление базы данных новыми данными при получении от другого экземпляра не влияет на все экземпляры, вместо этого у других экземпляров все еще будут объекты, которые еще не обновили свои данные, в нашем случае это self.scope['user']
, которые все еще будут иметь старые значения won_games, которые переопределят обновленные значения, когда мы попытаемся сохранить его, поэтому исправление заключается в том, чтобы просто добавить user = CustomUser.objects.get(id=user.id)
перед применением метода user.lose()