假设有三个模型,分别命名为Movie、Actor和Participation。
class Movie(models.Model):
identifier = models.CharField()
class Actor(models.Model):
name = models.CharField()
class Participation(models.Model):
movie_identifier = models.CharField()
actor = models.ForgeinKey(Actor, on_delete=models.CASCADE)
让我们假设我不能在参与模型中为电影使用ForgeinKey。
如何只需一个查询就可以检索到一部电影的所有参与记录?
如果我在参与表中有电影的外键,下面是解决方案:
qs = Movie.objects.filter(identifier="an_identiier").prefetch_related("participations_set")
在参与模式中没有电影外键的情况下,我如何做到这一点?
谢谢!
在设计数据库时(因此在设计模型时(最重要的事情之一是数据库规范化[Wikipedia]。
你说Participation
与多个模型有关,如Movie
、Series
、Episode
等。这意味着Movie
、Series
、Episode
都可以说具有共同的东西,或者它们可以说是另一个实体的专门化。让我们说Participatable
是因为没有更好的词,或者我们可以说Participatable
是Movie
的泛化,Series
、Episode
等
我们如何对这些进行建模?好吧,我们只会有一个额外的型号,我们的其他型号将有一个OneToOneField
,带有:
class Participatable(models.Model):
# Any common fields here
MOVIE = 'M'
SERIES = 'S'
TYPE_CHOICES = [
(MOVIE, 'Movie'),
(SERIES, 'Series'),
]
subject = models.CharField(max_length=1, choices=TYPE_CHOICES)
class Movie(models.Model):
# uncommon fields
participatable = models.OneToOneField(
Participatable,
on_delete=models.CASCADE,
related_name='movie',
)
class Series(models.Model):
# uncommon fields
participatable = models.OneToOneField(
Participatable,
on_delete=models.CASCADE,
related_name='series',
)
class Participation(models.Model):
participatable = models.ForgeinKey(Participatable, on_delete=models.CASCADE)
actor = models.ForgeinKey(Actor, on_delete=models.CASCADE)
除了这个我认为最适合这种建模的解决方案之外,你还可以使用内容类型框架,它基本上可以做你目前所做的事情。也就是说,它将使用一个存储相关id的字段,以及一个指向表中某个条目的外键,该条目将简单地描述该id用于哪个表。