How to pass `models_as_dict=False` into those Response Models?
jymchng opened this issue · 3 comments
I have two tables, Category
and Project
:
from pydantic import BaseModel
from typing import List, Optional
from sqlmodel import SQLModel, Field, Relationship
import inspect
from enum import Enum
class Category(SQLModel, table=True):
__table_name__ = 'category'
id: Optional[int] = Field(
primary_key=True,
index=True,
nullable=False,
)
category: str
project_id: Optional[int] = Field(
default=None, foreign_key='project.id', nullable=False)
class Project(SQLModel, table=True):
__table_name__ = 'project'
id: Optional[int] = Field(
primary_key=True,
index=True,
nullable=False,
)
categories: List[Category] = Relationship(
back_populates='project',
sa_relationship_kwargs={
"lazy": "selectin",
'cascade': 'all,delete,delete-orphan',
"primaryjoin": "category.project_id==project.id",
})
Definition of CategoryEnum
:
class CategoryEnum(str, Enum):
A = "A"
B = "B"
I have two read schemas:
class ICategoryRead(BaseModel):
category: CategoryEnum
class IProjectRead(BaseModel):
categories: List[ICategoryRead]
Let's say now I have this record:
one_project_read = IProjectRead(
categories=[
ICategoryRead(category=CategoryEnum.A)
]
)
When I call one_project_read.json()
that is what I get:
'{"categories": [{"category": "A"}]}'
I want it to be:
'{"categories": ["A"]}'
I managed to achieve this by doing two things:
- Add
class Config: ...
toIProjectRead
:
class IProjectRead(BaseModel):
categories: List[ICategoryRead]
class Config:
json_encoders = { <========= ADD THIS
ICategoryRead: lambda v: v.category,
}
- In my own small testing, pass the keyword argument
models_as_dict=False
into.json()
method:
>>> one_project_read.json(models_as_dict=False)
... '{"categories": ["A"]}'
Finally, my question is, how do I let your awesome create_response
function knows that I want models_as_dict=False
?
Thank you.
Hello, @jymchng the current create_response is a basic implementation that does not cover this case of responses but I think you can accomplish the same by not using create_response but instead creating the response object itself.
return IGetResponseBase[IProjectRead](data=one_project_read.json(models_as_dict=False))
Hello, @jymchng the current create_response is a basic implementation that does not cover this case of responses but I think you can accomplish the same by not using create_response but instead creating the response object itself.
return IGetResponseBase[IProjectRead](data=one_project_read.json(models_as_dict=False))
What should the annotation of the return value of the GET
function be?
def get_project(id: int) -> [what-should-be-this?]: