简体   繁体   中英

How to return Pydantic model using Field aliases instead of names in FastAPI?

My FastAPI call is not returning the data in correct Response model format. It is returning data in database model format.

My database model:

class cat(DBConnect.Base):
     __tablename__ = 'category'
     __table_args__ = {"schema": SCHEMA}
     cat_id = Column('cat_id',UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
     cat_desc = Column('cat_desc', TEXT, nullable=True)
     cat_h__l_name = Column('cat_h_l_name', TEXT, nullable=True)

My Pydantic Model:

claaa CamelModel(BaseModel):
    class config:
         alias_generator = to_camel
         allow_population_by_field_name = True

Class cat(CamelModel):
     cat_id =Field(alais='CatID', readonly=True)
     cat_description =Field(alias='CatDescription')
     cat_h__l_name = Field(alias='CatName')
     
    class config:
       orm_mode= True

My API CAll:

@router.patch('/cat/{id}/', response_model = 'cat')
def update_cat(response= Response, params: updatecat = Depends(updatecat)):
    response_obj = { resonse_code: status.HTTP_200_OK, 
    response_obj : {}    
    }
    
    response_obj = session.query() # It is returning the correct data from the database
    response.status_code = response_obj['response_code']
    
    return JSONResponse(response_obj['response_obj'], status_code = response_obj['response_code'])

Getting Response in below format:

     cat_id = 'some uuid'
     cat_desc = 'desc'
     cat_h__l_name = 'some h_l_name'

but I want response should return in below format:

CatID = 'some uuid'
CatDescription ='' some description'
CatName = 'Some cat name'

This code is not giving any errors (I have typed it, so might be some indentation or spelling mistake). The only issue is that the API doesn't return data in correct format. I have been stuck on it for a while. I am new to FastAPI. Please help me.

You can add response_model_by_alias=True to the endpoint. This is mentioned here in the documentation.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


def to_camel(string: str) -> str:
    return ''.join(word.capitalize() for word in string.split('_'))

class Item(BaseModel):
    name: str
    language_code: str
    
    class Config:
        alias_generator = to_camel
        allow_population_by_field_name = True    
            

fake_db = [
    Item(name='foo', language_code='en'),
    Item(name='bar', language_code='fr')
]


@app.get('/item/{item_id}', response_model=Item, response_model_by_alias=True)
def create_item(item_id: int):
    return fake_db[item_id]

However, as you seem to be returning a JSONResponse instead of a model in your endpoint, setting response_model_by_alias=True wouldn't have any effect. Hence, you could convert the model to a dictionary, using Pydantic's model.dict(...) , and set the by_alias argument to True .

On a side note, you cannot put a Pydantic model in a JSONResponse without first converting it to a dict , if you have data types, such as datetime , UUID , etc., that cannot be serialised. For those cases, you can use the jsonable_encoder to convert your data before passing it to a response. The jsonable_encoder will ensure that objects that are not serializable will be converted to a str .

from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder

@app.get('/item/{item_id}')
def create_item(item_id: int):
    return JSONResponse(jsonable_encoder(fake_db[item_id].dict(by_alias=True)), status_code=200)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM