如何在 Django 中使用一个查询在没有 FK 的情况下检索相关实例
How to retrieve related instances without FK using one query in django
假设有三个名为 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。
如何通过一次查询获取一部电影的所有参演记录?
如果我在参与中有电影的外键,这是解决方案table:
qs = Movie.objects.filter(identifier="an_identiier").prefetch_related("participations_set")
如果 Participation 模型中没有 Movie 外键,我该如何执行此操作?
谢谢!
设计数据库(因此在设计模型时)最重要的事情之一是 database normalization [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)
除了我认为最适合此类建模的解决方案之外,您还可以使用 content-types framework,它基本上可以完成您当前所做的工作。也就是说,它将使用一个存储相关 ID 的字段以及一个指向 table 中条目的外键,该条目将简单地描述此 ID 用于哪个 table。
假设有三个名为 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。
如何通过一次查询获取一部电影的所有参演记录?
如果我在参与中有电影的外键,这是解决方案table:
qs = Movie.objects.filter(identifier="an_identiier").prefetch_related("participations_set")
如果 Participation 模型中没有 Movie 外键,我该如何执行此操作?
谢谢!
设计数据库(因此在设计模型时)最重要的事情之一是 database normalization [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)
除了我认为最适合此类建模的解决方案之外,您还可以使用 content-types framework,它基本上可以完成您当前所做的工作。也就是说,它将使用一个存储相关 ID 的字段以及一个指向 table 中条目的外键,该条目将简单地描述此 ID 用于哪个 table。