I am using mysql database and it's doesn't support list if I stored sting like "apple","banana" in my mysql database then when using get method fastapi how to convert theme from string to list like ["apple","banana"]. I tried this but didn't work and also not getting the image fields until I remove @property.
class Shop_page(BaseModel):
product_title: str
product_image: str
class Config():
orm_mode = True
@property
def product_image(self):
return self.product_image.split(",")
here is my get method
@router.get("/shop_page", response_model=List[schemas.Shop_page],status_code=status.HTTP_200_OK)
async def create_variations(db: Session = Depends(get_db)):
parent_item = db.query(models.ParentProduct).all()
return parent_item
my result look like now
[
{
"product_title": "DEMO PRODUCT",
"product_image": "image1_url,image2_url"
}
]
my expected result will be look like this
[
{
"product_title": "DEMO PRODUCT",
"product_image": ["image1_url,image2_url"]
}
]
CodePudding user response:
Pydantic does not support @property decorator serializing
And I think you can just override from_orm
method as follows:
from typing import Type, Any
from pydantic import BaseModel, validator
class ShopPage(BaseModel):
product_title: str
product_image: list
class Config:
orm_mode = True
def from_orm(cls: Type['Model'], obj: Any):
if hasattr(obj, "product_image") and isinstance(obj.product_image, str):
obj.product_image = obj.product_image.split(",")
return super().from_orm(obj)
CodePudding user response:
This is what validators are for. But you need to define the schema the way you actually want it, not the way you receive it from your ORM. That means product_image
should be annotated as a list[str]
and your validator with pre=True
will handle the case, if you try and initialize it with a string instead:
from pydantic import BaseModel, validator
class ShopPage(BaseModel):
product_title: str
product_image: list[str]
class Config:
orm_mode = True
@validator("product_image", pre=True)
def split_urls(cls, v: object) -> object:
if isinstance(v, str):
return v.split(",")
return v
if __name__ == "__main__":
class TestORM:
product_title = "foo"
product_image = "bar,baz"
obj = ShopPage.from_orm(TestORM)
print(obj.json(indent=2))
Output:
{
"product_title": "foo",
"product_image": [
"bar",
"baz"
]
}
The advantage of the validator approach is that it will apply regardless of how you initialize ShopPage
and can even apply during assignment, if you configure your model with validate_assignment = True
. So even if you do ShopPage(product_title="a", product_image="b,c")
, you'll get the product_image
as a list.