Хорошо, ваша проблема здесь:
class Battletest(models.Model):
messages = []
opponent = ""
Это определяет messages
и opponent
как class атрибуты - атрибуты, которые принадлежат самому объекту класса и как таковыеделится между всеми экземплярами класса, превращая их практически в глобальные переменные (поскольку объекты класса являются синглетонами).
Здесь вы хотите сделать messages
атрибутом экземпляра, определив int в инициализаторе (вот для чего он):
class Battletest(models.Model):
fightlog = models.TextField()
def __init__(self, *args, **kwargs):
# let Model do it's own stuff !!!
super(Battletest, self).__init__(*args, **kwargs)
# and add our ones:
self.messages = []
self.opponent = None
В качестве примечания: такие ошибки часто встречаютсяпризнак того, что кто-то вроде «запрыгнул» в Django без предварительного изучения основ Python и ошибочно полагает, что поскольку модели Django используют атрибут класса для определения полей БД, синтаксис класса Python такой же, как в Java или PHP, где вы определяете атрибуты на верхнем уровне класса,Но это не то, как работает Python , и я очень настоятельно рекомендую, чтобы на этом этапе вы все остановили и сделали весь официальный урок по Python - это сэкономит вам много времени и боли, действительно,
В качестве примечания второй стороны: в контексте веб-приложения на стороне сервера вы хотите избежать любого (1022) глобального (изменяемого) состояния в вашем коде.Каждый бит изменяемого глобального состояния должен существовать в некоторых базах данных, ваших моделях, сеансах, независимо от того, является ли он внешним по отношению к вашему коду и может совместно использоваться многими процессами - потому что в типичной производственной настройке ваше приложение будет обслуживаться многими различными процессами (дадаже если у вас есть один единственный передний HTTP-сервер, он, как правило, будет управлять пулом процессов django, и запросы будут произвольно отправлены любому из этих процессов.
Теперь у вас есть еще одна проблема:
def eof(self):
# ...
self.fightlog = self.messages
Вы определили fightlog
как текстовое поле, но вы назначаете ему список списков.То, что будет сохранено, будет текстовым представлением списка, что не очень удобно.
Теоретически, то, что у вас здесь есть, это отношение один ко многим (в Battletest есть много Посланий), поэтому правильным реляционным дизайном будет использование отдельной модели Message
с ForeignKey
на Battletest
- как показано в учебнике (вы сделали учебник, не так ли?).
Теперь, если вы действительно настаиваете на денормализации этого, лучшее (не менее худшее) решение - это сериализовать messages
до json
в save()
время и десериализовать его обратно в Python в инициализаторе.Это можно сделать вручную:
import json
class Battletest(models.Model):
fightlog = models.TextField()
def __init__(self, *args, **kwargs):
# let Model do it's own stuff !!!
super(Battletest, self).__init__(*args, **kwargs)
# and add our ones:
if self.fightlog:
self.messages = json.loads(self.fightlog)
else:
self.messages = []
self.opponent = None
# ...
def save(self, *args, **kwargs):
self.fightlog = json.dumps(self.messages)
super(Battletest, self).save(*args, **kwargs)
или с помощью JSONField
(который более или менее автоматически позаботится об этом), если ваша СУБД поддерживает это.Поиск в Google для «django JSONField» должен дать некоторые подсказки ...
О, да ... Вы дублировали код здесь:
class Battletest(models.Model):
# ...
def draft(self, opponent):
CHARACTERS= (
(0, 'Confident Hacker'),
(1, 'Confused Coder'),
)
self.opponent = CHARACTERS[int(opponent)][1]
и здесь:
class SelectCharacter(forms.Form):
CONFIDENTHACKER = 0
CONFUSEDCODER = 1
CHARACTERS= (
(CONFIDENTHACKER, 'Confident Hacker'),
(CONFUSEDCODER, 'Confused Coder'),
)
character = forms.ChoiceField(choices=CHARACTERS)
Вы хотите вычленить это, чтобы у вас была единственная точка истины:
class Battletest(models.Model):
CONFIDENTHACKER = 0
CONFUSEDCODER = 1
CHARACTERS= [
(CONFIDENTHACKER, 'Confident Hacker'),
(CONFUSEDCODER, 'Confused Coder'),
]
def draft(self, opponent):
self.opponent = self.CHARACTERS[int(opponent)][1]
и в ваших формах.py:
from . models import Battletest
class SelectCharacter(forms.Form):
character = forms.ChoiceField(choices=Battltest.CHARACTERS)