Есть ли сквозная модель в Foreignkey в Foreignkey, как во многих местах? - PullRequest
0 голосов
/ 10 июля 2019

Я начинаю киберспортивный киберспорт.У меня есть класс под названием игра и турнир.Турнир имеет иностранный ключ с игрой.В игре есть объекты pubg и clashroyale.Когда Турнир создается с помощью игры pubg, он должен иметь атрибут с именем "выигрыш_пер_циллера".но не с другими играми.Он должен быть уникальным для того Турнира, когда он создан с этой игрой.Как я могу это сделать?

Я думал об использовании manytomanyfield, но в одном турнире есть только одна игра.так что это должно быть чужой.Я ожидаю, что в этом турнире появятся специальные атрибуты, которые я смогу повторить на странице с подробностями.

'' '

class Tournament(models.Model):
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    players = models.ManyToManyField(User,through="Subscription")
    max_players = models.IntegerField(default=100)
    tourney_type = models.CharField(max_length=20)
    price = models.IntegerField()
    time = models.DateTimeField()
    tourney_id = models.CharField(max_length=50)
    tourney_pass = models.CharField(max_length=15)
    first_prize = models.IntegerField()
    second_prize = models.IntegerField()
    third_prize = models.IntegerField()

' ''

'' '

class Game(models.Model):
    users = models.ManyToManyField(User, through="Membership")
    name = models.CharField(max_length=20)
    desc = models.TextField()

'' '

1 Ответ

0 голосов
/ 10 июля 2019

Вы можете создать абстрактные модели Game, PubgGame и ClashRoyaleGame, которые наследуются от вашей абстрактной модели. Это даст вам две основные гибкости:

  1. Поскольку Game будет абстрактной моделью, для нее не будет создано никакой таблицы. У вас будут только столы для PubgGame и т. Д. Моделей игр.
  2. Вы можете добавить определенные поля для каждой игры, такие как prize_per_kill.

Но при использовании этого решения возникнет проблема; Ваши абстрактные модели нельзя использовать в качестве ForeignKey в других моделях. Поэтому вам нужно найти способ представить свои модели PubgGame и ClashRoyaleGame в одном поле ForeignKey. Для этого в Django есть специальное поле: GenericForeignKey . Вам нужно указать CoontentType и PositiveIntegerField на свой GenericForeignKey, чтобы иметь возможность хранить идентификаторы первичного ключа ваших игровых моделей.

# models.py
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models

class Game(models.Model):
    users = models.ManyToManyField(User, through="Membership")
    name = models.CharField(max_length=20)
    desc = models.TextField()

    class Meta:
        abstract = True

class PubgGame(Game):
    prize_per_kill = models.TextField() # I dont know what prize_per_kill means :)

class ClashRoyaleGame(Game):
    some_other_field = models.TextField()

class Tournament(models.Model):
    players = models.ManyToManyField(User,through="Subscription")
    max_players = models.IntegerField(default=100)
    tourney_type = models.CharField(max_length=20)
    price = models.IntegerField()
    time = models.DateTimeField()
    tourney_id = models.CharField(max_length=50)
    tourney_pass = models.CharField(max_length=15)
    first_prize = models.IntegerField()
    second_prize = models.IntegerField()
    third_prize = models.IntegerField()

    # GenericForeignKey related fields
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    game = GenericForeignKey('content_type', 'object_id')

Тогда вы можете использовать эти поля как:

>>> from your_ap.models import Tournament, PubgGame
>>> pubg_game = PubgGame.objects.create(prize_per_kill="some value")
>>> tournament = Tournament.objects.create(game=pubg_game) # I'm not setting other fields for simplicity.
>>> tournament.save()
>>> tournament.game_object # This will give you a PubgGame model object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...