Как исправить «более одного внешнего ключа» Джанго - PullRequest
0 голосов
/ 25 января 2019

Я новичок в Django (использую версию: 2.1.5) (Python 3.6) и пытаюсь возиться с некоторыми моделями.Я строю шахматную базу данных.Это зависит от 3 моделей, игроков, игры и ходов, составляющих игру.Для каждой игры есть белый игрок и черный игрок, оба из класса игрока.Это вызывает ошибку:

<'class 'chessengine.admin.GameInline'>: (admin.E202) 'chessengine.Game' has more than one ForeignKey to 'chessengine.Player'.

Я попытался использовать имена ссылок, которые удалили ранее связанную ошибку, но не будут иметь дело с вышеупомянутой.


//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']

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Так как Game model имеет несколько ForeignKey для Player model.Таким образом, при определении TabularInline for Game ie. GameInline необходимо добавить fk_name к GameInline

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

Подробнее о fk_name здесь

0 голосов
/ 25 января 2019

Вы не можете иметь две ссылки на таблицу игроков таким образом. Вам нужно иметь type для игрока (и, возможно, использовать поля выбора), которое будет white или black:

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)

РЕДАКТИРОВАТЬ: Похоже, что вы можете иметь две ссылки на стол игрока, но я, скорее всего, все же реализую выбор или подобное решение.

...