Есть ли альтернатива использованию общих внешних ключей для обработки похожих деревьев моделей?

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

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)

То, что вы выбираете, чтобы идентифицировать поле постороннего ключа до вас, но логическое значение известно его небольшим размером в базе данных.

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