在 `tortoise.field.ForeignKeyField` 中使用关键字`related_name`

Posted

技术标签:

【中文标题】在 `tortoise.field.ForeignKeyField` 中使用关键字`related_name`【英文标题】:Usage of keyword `related_name` in `tortoise.field.ForeignKeyField` 【发布时间】:2021-12-15 03:47:52 【问题描述】:

我已经阅读了 Tortoise-ORM 的文档,但至少对我而言,文档并不清楚 tortoise.field.ForeignKeyField 中的关键字 related_name。它仅声明:

related_name:
    The attribute name on the related model to reverse resolve the foreign key.

我正在使用 Aerich(Tortoise-ORM 迁移管理器),但在我的模型中我看不到对 related_name 的单一引用。我还检查了数据库Postgres,找不到任何关于它的参考资料。也许我不知道去哪里找。

不幸的是,在 Tortoise-ORM 文档中没有关于此的简单实用示例。

我有一个非常简单的模型,例如:

import tortoise

class Toy(tortoise.models.Model):
    id = tortoise.fields.IntField(pk=True)
    name = tortoise.fields.CharField(max_length=32)
    owner = tortoise.fields.ForeignKeyField("models.Person", related_name='toys_owner')
    builder = tortoise.fields.ForeignKeyField("models.Person", related_name='toys_builder')

class Person(tortoise.models.Model):
    id = tortoise.fields.IntField(pk=True)
    name = tortoise.fields.CharField(max_length=32)


async def main():
    await tortoise.Tortoise.init(
            db_url='sqlite://:memory:',
            modules='models': ["__main__"]
    )
    await tortoise.Tortoise.generate_schemas()

    person_a = await Person.create(name="Gepheto")
    person_b = await Person.create(name="Fairy")
    person_c = await Person.create(name="Nobody")
    pinocchio = await Toy.create(name="Pinocchio", builder=person_a, owner=person_b)
    print(pinocchio)
    await tortoise.Tortoise.close_connections()

if __name__ == '__main__':
    tortoise.run_async(main())

related_name 在这方面是如何工作的?

【问题讨论】:

【参考方案1】:

由于乌龟的灵感来自 Django,您可以查看Django docs 以获得类似的答案。当您想要到达 Person's Toys 时使用它。

person_a.toys_builder.all()

这就是为什么它被称为“反向解析”事件。

【讨论】:

=) 感谢丹尼兹。是的。我找到。使用别人的文档太糟糕了。 =)【参考方案2】:

经过几次尝试...

related_name 值可用作外部模型中引用的名称,以反向访问它。

让我们先显示前进方向。在给出的示例中,从 Toy 模型实例(在本例中为 pinocchio),找到他的 builderowner

print(f"This is pinnochio owner pinnochio.owner.name")
print(f"This is pinnochio builder pinnochio.owner.builder")

related_name 允许我们在相反的方向上做同样的事情,从ownerbuilder,找到他/她的玩具并对其进行迭代。例如:

person_b_owned_toys = await person_b.toys_owner.all()

for toy in person_b_owned_toys:
    print(toy.name)

除了all()方法外,还可以使用filter()方法。返回一个QuerySet,仅包含与过滤器匹配的条目。例如:

person_b_owned_toys = await person_b.toys_owner.filter(name='Pinocchio')

for toy in person_b_owned_toys:
    print(toy.name)

filter 参数上的有效keys 反方向是来自Toys,而不是来自Person

【讨论】:

以上是关于在 `tortoise.field.ForeignKeyField` 中使用关键字`related_name`的主要内容,如果未能解决你的问题,请参考以下文章

秋的潇洒在啥?在啥在啥?

上传的数据在云端的怎么查看,保存在啥位置?

在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?

存储在 plist 中的数据在模拟器中有效,但在设备中无效

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据