Использование ключевого слова `related_name` в `tortoise.поле.ForeignKeyField`

#python #postgresql #tortoise-orm

Вопрос:

Я прочитал документацию Tortoise-ORM, но, по крайней мере, для меня, в документации неясно ключевое related_name слово in tortoise.field.ForeignKeyField . В нем указано только:

 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:

Поскольку tortoise вдохновлен Django, вы можете проверить документы Django, чтобы получить похожие ответы. Используется, когда вы хотите получить доступ к игрушкам пользователя.

 person_a.toys_builder.all()
 

Вот почему это называется событием «обратного разрешения».

Комментарии:

1. =) спасибо Дениз. ДА. Я нашел это. Слишком плохо использовать чужую документацию. =)

Ответ №2:

После нескольких попыток…

related_name Значение может использоваться как имя, на которое будет ссылаться внешняя модель, чтобы получить к нему доступ в обратном направлении.

Давайте сначала покажем направление вперед. В приведенном примере из экземпляра игрушечной модели (в данном случае pinocchio ) найдите его builder или owner с помощью:

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

Это related_name позволяет нам сделать то же самое в противоположном направлении, от owner или builder , найти его / ее игрушки и перебрать их. Например:

 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)
 

Допустимый keys filter параметр on в обратном направлении — это параметр from Toys , а не from, Person .