Open xalien10 opened 10 months ago
@uriyyo any updates about this question for underlying related fields data?
Hi @xalien10,
I'm sorry for not getting back to you sooner.
Here is code examples that might help you:
from fastapi import FastAPI
from tortoise import Tortoise
from tortoise.contrib.fastapi import register_tortoise
from tortoise.contrib.pydantic import pydantic_model_creator
from tortoise.fields import DatetimeField, ForeignKeyField, IntField, ReverseRelation, TextField
from tortoise.models import Model
from fastapi_pagination import Page, add_pagination
from fastapi_pagination.ext.tortoise import paginate
class User(Model):
id = IntField(pk=True)
name = TextField()
created_at = DatetimeField(auto_now_add=True)
user_roles: ReverseRelation["UserRole"]
class UserRole(Model):
id = IntField(pk=True)
name = TextField()
created_at = DatetimeField(auto_now_add=True)
user = ForeignKeyField("models.User", related_name="user_roles")
async def init():
joe = await User.create(name="Joe")
jane = await User.create(name="Jane")
await UserRole.create(name="admin", user=joe)
await UserRole.create(name="user", user=joe)
await UserRole.create(name="user", user=jane)
Tortoise.init_models(["__main__"], "models")
UserList = pydantic_model_creator(User, name="UserList")
app = FastAPI()
add_pagination(app)
register_tortoise(
app,
generate_schemas=True,
config={
"connections": {
"default": "sqlite://:memory:",
},
"apps": {
"models": {
"models": ["__main__"],
"default_connection": "default",
},
},
},
)
app.add_event_handler("startup", init)
@app.get("/users")
async def route() -> Page[UserList]:
return await paginate(User, prefetch_related=True)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app)
My suggestions for where the problem could be on your side:
Tortoise.init_models
before calling pydantic_model_creator
. Please, take a look here - https://tortoise.github.io/contrib/pydantic.html#pydanticmeta-callablesprefetch_related
when paginate queries with relationship.@uriyyo
Instead of model User
, can we use queryset?
like this one -
@app.get("/users")
async def route() -> Page[UserList]:
return await paginate(await User.filter(name="John Snow"), prefetch_related=True)
@xalien10 Sure
from fastapi_pagination.ext.tortoise import paginate
@app.get("/users")
async def route() -> Page[UserList]:
return await paginate(User.filter(name="Joe"), prefetch_related=True)
@uriyyo do we need to explicitly write the reverse relation like user_roles
in User
model?
as you can see here model_validate
failing.
And in the items, it can get the queryset properly. So, I'm wondering what could go wrong?
I've added early init in the schema before creating any Pydantic
model from tortoise-orm
do we need to explicitly write the reverse relation like user_roles in User model?
Yup, you need to do it
@xalien10 Any updates? Can I close this issue?
Actually, I tried to use this approach but it didn't help with my service layer with repository pattern. I'm extremely sorry that I couldn't report it earlier than now
Is there anything I can help you with?
I was trying to use pagination for
User
model whereUserRole
has a related relationuser_roles
withUser
model. When I tried to usepydantic_model_creator
fromtortoise-orm
to generate schema for pagination, it is raisingpydantic_core._pydantic_core.ValidationError
due to relation while model validation.But if we exclude it explicitly in
pydantic_model_creator
throughexclude
, it is able to generate pagination correctly.Before applying pagination the actual output was following:
@uriyyo any suggestion about how to achieve this structure using
fastapi-pagination
andtortoise-orm
?