tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.37k stars 355 forks source link

Nested serialised objects from tortoise orm #1139

Open ibolit opened 2 years ago

ibolit commented 2 years ago

Describe the bug Nesting related models by foreign key doesn't work for Tortoise Orm objects: I have two models: Events and Tournament, and Event has a foreign key relation to Tournament. I want to select an event from the db and return it in my response such that the serialised event also contains the related tournament object nested in it:

{
    "name": "my event",
    "tournament": {
        "name": "my tournament"
    }
}

Whatever I tried, the best I could do is get the tournament_id in the serialised event.

To Reproduce Steps to reproduce the behavior, preferably a small code snippet.

# models.py
class Tournament(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=255)

class Event(Model):
    name = fields.CharField(max_length=255)
    tournament = fields.ForeignKeyField('models.Tournament', related_name='events')

# as per the https://tortoise-orm.readthedocs.io/en/latest/examples/fastapi.html example, but I also tried using the Pydantic models
Event_Pydantic = pydantic_model_creator(Event, name='Event', include=("name", 'tournament'))
Tournament_Pydantic = pydantic_model_creator(Tournament, name='Tournament')

# main.py

app = FastAPI()

register_tortoise(
    app,
    db_url=TORTOISE_ORM['connections']['default'],
    modules={'models': ['models']},
    generate_schemas=True,
    add_exception_handlers=True,
)

@app.get('/events/', response_model=models.Event_Pydantic)
async def get_events():
    return await models.Event_Pydantic.from_queryset_single(
        models.Event.get(id=1).select_related('tournament')
    )

Expected behavior

{
  "name": "game one"
  "tournament": {
    "name": "my tournament"
  }
}

Actual behaviour:

{
  "name": "game one"
}

Additional context Add any other context about the problem here.

dinosaurtirex commented 2 years ago

It's difficult to understand why it happened, i guess it's more pydantic issue, then tortoise. May be you just selecting more than 1 record?

dinosaurtirex commented 2 years ago

And also i guess it's can't access tournaments because it's sub-key value, look at the source code:

image

image

image

look like its iterate only through first layer of the dict, for example:

{
   "key": 1, > this 
   "foo": {
              "key": 1 > but not this
              }
}