My scenario: I'm trying to build a database to track production schedules for different types of shows. I've mapped that out with the following model structure.
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)
But I'm now interested in tracking production of movies as well. This presents a challenge though, because movies don't have the same tree structure as TV. Something like this would be more fitting:
class Studio(models.Model):
...
class Movie(models.Model):
studio = models.ForeignKey(Studio)
...
class Production(models.Model):
movie = models.ForeignKey(Movie)
The problem here is that Production
and Studio
are exactly the same for both movies and TV (at least in this scenario), so I'm hesitant to have totally separate trees, because this would necessitate duplicating Production
. One for TV and one for Movies, when the only difference is the foreign key.
Does it make sense to use a GenericForeignKey
here? Where a production can either point at an Episode
or Movie
? I'm hesitant to do so because it sounds like the consensus is to avoid generic foreign keys, but I'm not sure how else to do so.
I faced a similar issue a while back, and I came to the conclusion that it would be more efficient (and less trouble later on) with 2 foreign keys, and 2 boolean variables informing the type in these tables.
Also from your code I see no reason to duplicate the Studio model as it is identical, and contains no unique foreign key field. Production model however can be written like this
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)
What you choose to identify the foreignkey field up to you but boolean is known for its small size in the database.