我正在创建一个基于浏览器的RPG,其中战斗机制被构建到一个名为“战斗”的模型中。它根据一些公式在英雄、怪物和物品模型上执行动作。每个动作都会在“战斗日志”中添加一条消息。一个玩家可以以一种形式对另一个玩家或NPC发起战斗。提交表单时,它调用相同的视图,创建战斗对象,起草角色,运行游戏机制。你知道吗
出于某种原因,旧的“Battle”对象仍然在这些视图的运行之间被“选中”,只要它在同一个web会话中。因此,即使我创建了一个新对象,旧的作战日志也会转移到这个新对象。 我做错什么了?你知道吗
更新了更多内容
第一个对象中的fightlog字段是正确的。 第二个对象中的fightlog字段是第一个对象数据加上新数据。 第三次格斗是第一次加第二次加第三次,以此类推
你知道吗视图.py你知道吗
def battle_log(request):
if request.session["last_battle"]:
pk = request.session["last_battle"]
b = Battletest.objects.get(pk=pk)
battle_log = b.fightlog
request.session["last_battle"] = ""
context = { 'battle_log' : battle_log, }
return render(request, 'battle.html', context)
else:
return redirect('/game/monster')
def fight_select_monster(request):
form = SelectCharacter()
if request.method=='POST':
form = SelectCharacter(request.POST)
if form.is_valid():
b = Battletest.objects.create()
b.draft(request.POST.get("character"))
b.start_fight()
b.round()
b.eof()
b.save()
request.session["last_battle"] = b.pk
return redirect('/game/fight/')
context = { 'form': form }
request.session["last_battle"] = ""
return render(request, 'fight.html', context)
你知道吗型号.py你知道吗
class Battletest(models.Model):
messages = []
fightlog = models.TextField()
opponent = ""
def draft(self, opponent):
CHARACTERS= (
(0, 'Confident Hacker'),
(1, 'Confused Coder'),
)
self.opponent = CHARACTERS[int(opponent)][1]
def start_fight(self):
self.messages.append([0, "You joined the battle."])
self.messages.append([0, self.opponent + "has appeared"])
def round(self):
# have character objects do stuff to eachother until
# some edge case is met.
self.messages.append([1, "You smack " + self.opponent + " in the face"])
self.messages.append([1, self.opponent + " decides to leave this stupid fight"])
def eof(self):
self.messages.append([2, "The fight is over and noone wins"])
self.fightlog = self.messages
你知道吗表单.py你知道吗
class SelectCharacter(forms.Form):
CONFIDENTHACKER = 0
CONFUSEDCODER = 1
CHARACTERS= (
(CONFIDENTHACKER, 'Confident Hacker'),
(CONFUSEDCODER, 'Confused Coder'),
)
character = forms.ChoiceField(choices=CHARACTERS)
好的,你的问题是:
这将
messages
和opponent
定义为类属性 -属于类对象本身的属性,因此在类的所有实例之间共享,使它们实际上成为全局变量(因为类对象是单例的)。你知道吗这里需要的是通过在初始值设定项中定义int使
messages
成为实例属性(这就是它的用途):作为旁注:这样的错误通常是有人在没有先学习Python的基础知识的情况下“跳进”Django的标志,并且错误地认为因为Django模型使用class attribute来定义db字段,Python的类语法与Java或PHP相同,在Java或PHP中,您在类的顶层定义属性。但是that's not how Python works我强烈建议您现在停止一切,完成整个官方的Python教程—这将为您节省大量的时间和痛苦,真的。你知道吗
第二点注意:在服务器端web应用的上下文中,您希望在代码中避免任何类型的(可变的)全局状态。每一个可变的全局状态都应该存在于一些数据库您的模型、会话中,只要它在您的代码之外,并且可以在许多进程之间共享—因为在典型的生产设置中,您的应用程序将由许多不同的进程提供服务(是的,即使您有一个HTTP前端服务器,它通常也会管理一个池)django进程,请求将被任意分派到这些进程中的任何一个)。
现在,你有另一个问题:
您将
fightlog
定义为一个文本字段,但要为其分配一个列表列表。保存的将是列表的文本表示,这不是很有用。你知道吗理论上,这里的关系是一对多的关系(一个Battletest有很多消息),所以正确的关系设计应该是使用一个不同的
Message
模型,在Battletest
-as shown in the tutorial上使用一个ForeignKey
(你做了教程,是吗?)。你知道吗现在,如果您真的坚持要对其进行反规范化,那么最好的(至少不那么糟糕)解决方案是在
messages
时间将json
序列化为save()
,然后在初始值设定项中将其反序列化回Python。这可以手动完成:或者使用
JSONField
(或多或少会自动处理这个问题),如果您的RDBMS支持的话。谷歌搜索“djangojsonfield”应该会提供一些提示。。。你知道吗哦,是的。。。这里有重复的代码:
在这里:
你想把这个因素考虑进去,这样你就有了一个单一的真理点:
在你的表单.py地址:
相关问题 更多 >
编程相关推荐