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
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. Finally I try to test the code by using 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. 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. 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).