#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
.