如何修复“多个外键” Django

时间:2019-01-24 21:47:21

标签: python django django-models django-admin

我是Django的新手(使用版本:2.1.5)(Python 3.6),并尝试弄乱某些模型。我正在建立国际象棋数据库。这依赖于3个模型,即玩家,游戏和构成游戏的移动。每场比赛都有一名白人球员和一名黑人球员,均为两名职业球员。这会引发错误:


//models.py


class Player(models.Model):

    name = models.CharField(max_length=200)
    birth_date = models.DateField('birthday')

    def game_count(self):
        return Player.objects.filter(Games__white_player=self.name).count() + Player.objects.filter(Games__black_player=self.name).count()


class Game(models.Model):

    number = models.IntegerField()
    date = models.DateField('date played')
    moves = models.IntegerField()
    white_player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='white_player')
    black_player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='black_player')
    result = models.CharField(max_length=8)

我尝试使用引用名称删除了一个较早的相关错误,但不会处理上述错误。


//admin.py

class GameInline(admin.TabularInline):

    inlines = [MoveInline]
    model = Game


class PlayerAdmin(admin.ModelAdmin):

    fieldsets = [
        ('Player Information',               {'fields': ['name', 'birth_date']}),
        ('Game Information', {'fields': ['date', 'player_white', 'player_black', 'result'], 'classes': ['collapse']}),
    ]
    inlines = [GameInline]
    list_display = ('name', 'birth_date', 'game_count')
    list_filter = ['name']
Delete from table2
where id not in(Select id from table1)

2 个答案:

答案 0 :(得分:1)

由于Game model具有多个Player model的外键。因此,在定义TabularInline for Game ie. GameInline时,您必须将fk_name添加到GameInline

class GameInline(admin.TabularInline):
    inlines = [MoveInline]
    model = Game
    fk_name = 'white_player`

详细了解fk_name here

答案 1 :(得分:0)

您不能以这种方式有两个对播放器表的引用。您应该为玩家准备一个type(并可能利用选择字段),该whiteblack

class Player(models.Model):

    PLAYER_TYPES = (("W", "White"), ("B", "Black")

    type = models.CharField(max_length=5, blank=False, null=False, choices=PLAYER_TYPES)
    name = models.CharField(max_length=200)
    birth_date = models.DateField('birthday')

def game_count(self):
    return Player.objects.filter(Games__white_player=self.name).count() + Player.objects.filter(Games__black_player=self.name).count()


class Game(models.Model):

    number = models.IntegerField()
    date = models.DateField('date played')
    moves = models.IntegerField()
    player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='player')
    result = models.CharField(max_length=8)

编辑:看来您可以拥有对播放器表的两个引用,但我可能仍会实施选择或类似的解决方案。