【问题标题】:Usage of keyword `related_name` in `tortoise.field.ForeignKeyField`在 `tortoise.field.ForeignKeyField` 中使用关键字`related_name`
【发布时间】: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 在这方面是如何工作的?

【问题讨论】:

    标签: python postgresql tortoise-orm


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2013-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      • 2013-09-14
      • 1970-01-01
      • 2015-01-18
      • 2014-03-30
      相关资源
      最近更新 更多