【发布时间】:2021-09-27 21:48:43
【问题描述】:
我正在 Django 中为多人战舰游戏创建一个项目,我正在尝试设置我的数据库以便记录游戏、玩家和用户操作,这里是 app/model.py 代码
from django.db import models
# Create your models here.
class Player(models.Model):
username = models.CharField(max_length=10,primary_key=True)
password = models.CharField(max_length=10)
class GameBoard(models.Model):
size = models.IntegerField(default=10)
state = models.CharField(max_length=500,default='')
class Game(models.Model):
game_id = models.AutoField(primary_key=True)
player1 = models.ForeignKey(Player,related_name='player1',blank = True,null=True,on_delete=models.SET_NULL)
player2 = models.ForeignKey(Player,related_name='player2',blank = True,null=True,on_delete=models.SET_NULL)
board = models.ForeignKey(GameBoard,related_name='game_board',on_delete=models.CASCADE)
def __str__(self):
return f'Game: {self.game_id}, player1: {self.player1}, player2: {self.player2}, board {self.board}'
class Action(models.Model):
GAME_ACTIONS = (
('a', 'Attack'),
('s', 'Surrender'),
)
player_action = models.ForeignKey(Player,related_name='player_action',null=True,on_delete=models.SET_NULL)
action = models.CharField(max_length=3, choices=GAME_ACTIONS)
game = models.ForeignKey(Game,related_name='played_in',on_delete=models.CASCADE)
然后我运行 makemigrations 并 migrate 来更新数据库。最后我尝试使用 manage.py shell 测试代码:
from battleship.models import *
p1 = Player('Alice','password1')
p1.save()
p2 = Player('Bob','password')
p2.save()
b = GameBoard()
b.save()
g = Game(player1 = p1,player2 = p2,board = b)
g.save()
当我运行此代码时,我收到以下错误:django.db.utils.IntegrityError: FOREIGN KEY constraint failed。我还尝试保存一个没有玩家的游戏:
g = Game(player1 = None,player2 = None,board = b)
g.save()
前面的代码可以正常执行,我还检查了数据库上保存的对象,它实际上保存正确。
我认为问题出在 p1 和 p2 上,但我不明白为什么,因为 board 也是外键。我假设这取决于 Player 模型中的 null=True ,但是我没有看到该参数存在的问题(如果删除了玩家,我想将现有游戏名称更新为 null 而不是在级联时删除) .
【问题讨论】:
-
我认为它与
Game模型中的相关名称冲突。您是否尝试更改player1和player2的相关名称或属性名称本身? -
我试过了,似乎有帮助,现在错误是 OperationalError: table Battleship_game has no column named p1_id (是的,我确实在更改后迁移了)
-
你能发布你更新的模型代码吗?
-
另外,在上面的示例中,您没有正确创建播放器对象。在创建对象时,您必须使用关键字参数。就像你正在使用
Game。 -
game_id = models.AutoField(primary_key=True) p1 = models.ForeignKey(Player,related_name='player1',blank = True,null=True,on_delete=models.SET_NULL) p2 = models. ForeignKey(Player,related_name='player2',blank = True,null=True,on_delete=models.SET_NULL) board = models.ForeignKey(GameBoard,related_name='game_board',on_delete=models.CASCADE)
标签: python django django-models