简体   繁体   English

Django 使用有效的外键抛出外键 IntegrityError

[英]Django throws a Foreign Key IntegrityError with a valid ForeignKey

I am creating a project in Django for a multiplayer battleship game, I am trying to set up my database so I can record games, players and user actions, here is the app/model.py code我正在 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)

Then I run makemigrations and migrate to update the database.然后我运行 makemigrations 和 migrate 以更新数据库。 Finally I try to test the code by using manage.py shell:最后我尝试使用 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()

When I run this code I receive the following error: django.db.utils.IntegrityError: FOREIGN KEY constraint failed.当我运行此代码时,我收到以下错误:django.db.utils.IntegrityError:FOREIGN KEY 约束失败。 I also tried to save a game with no players:我还尝试保存没有玩家的游戏:

g = Game(player1 = None,player2 = None,board = b)
g.save()

The previous code is able to execute without error, I also checked the saved object on the database and it actually saved it correctly.前面的代码能够无误地执行,我还检查了数据库中保存的对象,它实际上正确地保存了它。

I assume that the issue is with p1 and p2, however I don't understand why, since board is a foreign key as well.我认为问题出在 p1 和 p2 上,但是我不明白为什么,因为 board 也是外键。 I am assuming this depends on the null=True in the Player model, however I don't see the problem with that parameter being there (if a player is deleted I want to update the existing game names to null instead of deleting on cascade).我假设这取决于 Player 模型中的 null=True ,但是我没有看到该参数存在的问题(如果删除了玩家,我想将现有游戏名称更新为 null 而不是在级联上删除) .

The related_name in this case is what is used by the Player model to reference objects of the Game model.在这种情况下,related_name 是 Player 模型用来引用 Game 模型的对象的名称。 It is confusing in this case as the Player model can be referenced by either the Game.player_1 or Game.player_2 fields.在这种情况下令人困惑,因为玩家模型可以被 Game.player_1 或 Game.player_2 字段引用。 A ManyToMany field called players may make more sense here.在这里,称为玩家的 ManyToMany 字段可能更有意义。 Otherwise change the value of related_name to "game_1" and "game_2" or similar.否则,将related_name 的值更改为“game_1”和“game_2”或类似值。

This question explains related_name well 这个问题很好地解释了related_name

Django documentation on related_name 有关related_name 的Django 文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM