如何在django中使用一个查询检索没有FK的相关实例

如何在django中使用一个查询检索没有FK的相关实例,django,django-models,django-orm,Django,Django Models,Django Orm,假设有三个模型,分别命名为电影、演员和参与 class Movie(models.Model): identifier = models.CharField() class Actor(models.Model): name = models.CharField() class Participation(models.Model): movie_identifier = models.CharField() actor = models.ForgeinK

假设有三个模型,分别命名为电影、演员和参与

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")
在参与模型中没有电影外键的情况下,如何执行此操作


谢谢

在设计数据库(因此在设计模型时)时,最重要的事情之一是

您谈论的
参与
与多个模型相关,如
电影
系列
插曲
,等等。这意味着
电影
系列
插曲
都可以说有一些共同的东西,或者它们可以说是另一个实体的专业化,让我们说
可参与性
,因为没有更好的词,或者我们可以说
可参与性
电影
的一种推广,
系列
插曲

我们如何对这些进行建模?我们将有一个额外的模型,我们的其他模型将有一个
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用于哪个表。

为什么不能使用外键?你能解释一下原因吗?另外,do note
prefetch\u related
进行多个查询,只是它收集需要获取的对象并进行查询以将它们全部聚集在一起,所以至少进行了2次查询。如果表不维护关系,您希望如何返回表的记录。我想那是不可能的。有很多像电影这样的模型,比如连续剧,插曲。参与应该与所有人都有关系,我不想有多个FK。关于预回迁,它只有一个对数据库的调用,对吗?因此,您不会多次为网络延迟付费。@Moein您可以自己尝试并模拟预回迁:获取与任何电影相关的所有参与对象(
Participation.objects.filter(Movie\u identifier\u in=qs.values('identifier'))
),然后循环所有结果并附加到每部电影的列表中。“我不想有多个FK”可能不是让事情变得如此复杂的一个很好的理由:)@iain shelvington使用这种方式只向数据库发送一个请求?qs的所有元素都将被提取?例如,
list(qs[:50])
不会发送请求吗?