Есть ли альтернатива использованию общих внешних ключей для обработки похожих деревьев моделей?
Мой сценарий: я пытаюсь создать базу данных, чтобы отслеживать производственные графики для различных типов шоу. Я сопоставил это со следующей структурой модели.
class Studio(models.Model):
...
class Series(models.Model):
studio = models.ForeignKey(Studio)
...
class Season(models.Model):
series = models.ForeignKey(Series)
...
class Episode(models.Model):
season = models.ForeignKey(Season)
...
class Production(models.Model):
episode = models.ForeignKey(Episode)
Но теперь я заинтересован в отслеживании производства фильмов. Это создает проблему, потому что фильмы не имеют такую же древовидную структуру, как телевидение. Примерно так будет более уместно:
class Studio(models.Model):
...
class Movie(models.Model):
studio = models.ForeignKey(Studio)
...
class Production(models.Model):
movie = models.ForeignKey(Movie)
Проблема здесь в том, что Production
а также Studio
одинаковы как для фильмов, так и для телевидения (по крайней мере, в этом сценарии), поэтому я не решаюсь иметь совершенно разные деревья, потому что это потребует дублирования Production
, Один для телевидения и один для фильмов, когда единственным отличием является внешний ключ.
Имеет ли смысл использовать GenericForeignKey
Вот? Где производство может указывать на Episode
или же Movie
? Я не решаюсь сделать это, потому что кажется, что консенсус заключается в том, чтобы избегать общих внешних ключей, но я не уверен, как еще это сделать.
1 ответ
Некоторое время назад я столкнулся с подобной проблемой и пришел к выводу, что она будет более эффективной (и в дальнейшем будет меньше проблем) с 2 внешними ключами и 2 логическими переменными, сообщающими тип в этих таблицах.
Также из вашего кода я не вижу смысла дублировать модель Studio, поскольку она идентична и не содержит уникального поля внешнего ключа. Однако модель производства может быть написана так
class Production(models.Model):
movie = models.ForeignKey(Movie, null=True)
episode = models.ForeignKey(Episode, null=True)
is_movie = models.BooleanField(null=False)
is_episode = models.BooleanField(null=False)
То, что вы выбираете, чтобы идентифицировать поле постороннего ключа до вас, но логическое значение известно его небольшим размером в базе данных.