gpt4 book ai didi

django - 解决 Django 的 ManyToManyField 外键限制

转载 作者:行者123 更新时间:2023-12-02 11:34:09 25 4
gpt4 key购买 nike

我有一个 Django 应用程序,它必须使用其他来源提供的数据库。 我无法更改架构。下面的所有内容都是由inspectdb生成的:

class Family(models.Model):
persistanceid = models.BigIntegerField(primary_key=True)

class Spouseref(models.Model):
persistanceid = models.BigIntegerField(primary_key=True)

class Family_spouseref(models.Model):
family_persistanceid = models.ForeignKey(Family, db_column='family_persistanceid')
wiferefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='wiferefs_persistanceid', blank=True, related_name='wiferefs')
husbandrefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='husbandrefs_persistanceid', blank=True, related_name='husbandrefs')
childrefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='childrefs_persistanceid', blank=True, related_name='childrefs')

ManyToManyField 无法在 Family 下工作,因为映射表 Family_spouseref 有多个指向 Spouseref 的外键。给定这个模式,完成这样的事情最有效的方法是什么:

fam = Family.objects.get(persistanceid=id)
husbands = fam.husbands.all()
wives = fam.wives.all()
children = fam.children.all()

更新:

根据要求...以下功能是我尝试在上面的 Family 模型中添加的功能。

我尝试了原始 SQL,如下所示:

    def husbands(self):
return Spouseref.objects.raw ('SELECT * FROM spouseref WHERE spouseref.persistanceid IN (SELECT husbandrefs_persistanceid FROM family_spouseref WHERE family_persistanceid=%s);', [self.persistanceid])

这可行,但是原始 SQL 真的是最好的方法吗?看起来,我通过这种方式失去了很多常用的对象方法。

当我尝试通过 ORM 执行此操作时,它一直想认为 Family_spouseref 表具有列 id,但它显然没有。

Family_spouseref.objects.get(family_persistanceid=self.persistanceid)

制作:

[DEBUG] django.db.backends: (0.001) SELECT "family_spouseref"."id", "family_spouseref"."family_persistanceid", "family_spouseref"."wiferefs_persistanceid", "family_spouseref"."husbandrefs_persistanceid", "family_spouseref"."childrefs_persistanceid" FROM "family_spouseref" WHERE "family_spouseref"."family_persistanceid" = 45036  LIMIT 21; args=(45036,)
DatabaseError: column family_spouseref.id does not exist
LINE 1: SELECT "family_spouseref"."id", "family_spouseref"."family_p...

我也尝试过:

Family_spouseref.objects.get(Q(family_persistanceid=self.persistanceid) | Q(husbandrefs_persistanceid__isnull=False))

这产生了相同的 ID 错误,但确实尝试遵循 FK 关系:

[DEBUG] django.db.backends: (0.000) SELECT "family_spouseref"."id", "family_spouseref"."family_persistanceid", "family_spouseref"."wiferefs_persistanceid", "family_spouseref"."husbandrefs_persistanceid", "family_spouseref"."childrefs_persistanceid" FROM "family_spouseref" LEFT OUTER JOIN "spouseref" ON ("family_spouseref"."husbandrefs_persistanceid" = "spouseref"."persistanceid") WHERE ("family_spouseref"."family_persistanceid" = 45036  OR "spouseref"."persistanceid" IS NOT NULL) LIMIT 21; args=(45036,)
DatabaseError: column family_spouseref.id does not exist
LINE 1: SELECT "family_spouseref"."id", "family_spouseref"."family_p...

我还惊讶地发现,通过调试,它调用相同(错误)语句的频率(8 次)与原始 SQL(它调用两次)的频率不同。 (还是两次!)

我真的很想知道 Django 的官方方式来遍历这些表,而不是完全忽略 ORM 并执行原始 SQL。谢谢。

最佳答案

您收到的错误是因为 Django 默认设置一个“id”字段作为主键,如果没有字段将“primary_key=True”声明为参数(例如,您在 Family 模型中这样做)。因此,当您尝试获取模型对象时,您总是会收到如下错误:

DatabaseError: column family_spouseref.id does not exist

首先,为该模型指定一个主键。我打赌它有一个。如果没有,也许您只想阅读this 。现在,关于你的效率问题,你可以这样做:

def husbands(self):
husbandrefs_for_family = Family_spouseref.objects.filter(
family_persistanceid=self.persistanceid,
).values_list('husbandrefs_persistanceid',flat=True)

return Spouseref.objects.filter(
persistanceid__in=husbandrefs_for_family,
)

虽然看起来您正在执行 2 个查询,但您会看到 Django 仅执行了一个查询(嗯,这是一个带有子查询的查询,就像您在 SQL 中所做的那样)。

子查询的values_list部分用于仅引入所需表的列。这是您想要的 SLQ 语句的 select hubrefs_persistanceid 部分。

希望对你有帮助!

关于django - 解决 Django 的 ManyToManyField 外键限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10964085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com