Джанго - Как построить модель среднего м2, которая подходит? / лучшая практика

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

В любом случае, я пытаюсь создать приложение, которое будет показывать разные обладатели титула, чемпионаты и тому подобное. Прочитав документацию по Django, я понял, что лучше использовать промежуточные модели. Мой старый models.py выглядит так:

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    [...]

class Team(models.Model):
    name = models.CharField(max_length=64)
    team_member_one = models.ForeignKey(Person)
    team_member_two = models.ForeignKey(Person)

class Championship(models.Model):
    name = models.CharField(max_length=128)
    status = models.BooleanField(default=True)

class Titleholder(models.Model):
    championship = models.ForeignKey(Championship)
    date_won = models.DateField(null=True,blank=True)
    date_lost = models.DateField(null=True,blank=True)
    titleholder_one = models.ForeignKey(Person,related_name='titleholder_one',null=True,blank=True)
    titleholder_two = models.ForeignKey(Person,related_name='titleholder_two',null=True,blank=True)

Чемпионаты могут выигрывать как отдельные лица, так и команды, в зависимости от того, чемпионат ли это в одиночном разряде или в командном зачете, поэтому мне пришлось использовать внешние ключи в классе Titleholder. Глядя на документацию по Django, это кажется ложным. С другой стороны, для меня, как для начинающего, промежуточная модель в данном примере просто никак не подходит для моей модели.

Короче говоря: кто-нибудь может указать мне правильное направление, как правильно построить модель? Примечание: это всего лишь вопрос о том, как создавать модели и отображать их в админке Django, я даже не говорю о создании шаблонов на данный момент.

Помощь будет принята с благодарностью! Заранее спасибо, ребята.

1 ответ

Так что я возьму это с нуля. Вы, кажется, немного новичок в моделировании баз данных ER. Если бы я пытался сделать то, что вы делаете, я бы создал свои модели следующим образом.

Во-первых, Team была бы моей "угловой" моделью (я использую этот термин для обозначения моделей, не имеющих полей FK), а затем модель Person вступит в игру следующим образом.

class Team(models.Model):
    name = models.CharField(max_length=64)

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    team = models.ForeignKey(to=Team, null=True, blank=True, related_name='members')

Это эффективно делает модели масштабируемыми, и даже если в команде никогда не будет более двух человек, это хорошая практика.

Далее идет модель чемпионата. Я бы связал эту модель напрямую с моделью Person как отношение "многие ко многим" с "сквозной" моделью следующим образом.

class Championship(models.Model):
    name = models.CharField(max_length=64)
    status = models.BooleanField(default=False) # This is not a great name for a field. I think should be more meaningful.
    winners = models.ManyToManyField(to=Person, related_name='championships', through='Title')

class Title(models.Model):
    championship = models.ForeignKey(to=Championship, related_name='titles')
    winner = models.ForeignKey(to=Person, related_name='titles')
    date = models.DateField(null=True, blank=True)

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

Другой подход, который можно использовать, - это использование поля GenericForeignKey для создания поля, которое может быть FK либо для модели Team, либо для модели Person. Или еще одна вещь, которая может быть изменена, это добавление другой модели для хранения информации о каждом проведении чемпионата. Есть много способов, и ни один правильный путь не существует.

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

Другие вопросы по тегам