5

I have a router that fetches all data from the database. Here is my code:

@router.get('/articles/', response_model=List[articles_schema.Articles])
async def main_endpoint():
    query = articles_model.articles.select().where(articles_model.articles.c.status == 2)
    return await db.database.fetch_all(query)

The response is an array that contains JSON objects like this

[
    {
        "title": "example1",
        "content": "example_content1"
    },
    {
        "title": "example2",
        "content": "example_content2"
    },
]

But I want to make the response like this:

{
    "items": [
        {
            "title": "example1",
            "content": "example_content1"
        },
        {
            "title": "example2",
            "content": "example_content2"
        },
    ]
}

How can I achieve that? Please help. Thank you in advance

2 Answers 2

10

Also, You can create a custom responses using generic types as follow if you plan to reuse a response template

from typing import Any, Generic, List, Optional, TypeVar
from pydantic import BaseModel
from pydantic.generics import GenericModel

DataType = TypeVar("DataType")

class IResponseBase(GenericModel, Generic[DataType]):
    message: str = ""
    meta: dict = {}
    items: Optional[DataType] = None

@router.get('/articles/', response_model=IResponseBase[List[Articles]])
async def main_endpoint():
    query = articles_model.articles.select().where(articles_model.articles.c.status == 2)
    items=await db.database.fetch_all(query)
    return IResponseBase[List[Articles]](items=items)

You can find a FastAPI template here https://github.com/jonra1993/fastapi-alembic-sqlmodel-async/blob/main/fastapi-alembic-sqlmodel-async/app/schemas/response_schema.py

Sign up to request clarification or add additional context in comments.

Comments

8

You could simply define another model containing the items list as a field:

from pydantic import BaseModel
from typing import List

class ResponseModel(BaseModel):
    items: List[articles_schema.Articles]

and use it in the response:

@router.get('/articles/', response_model=ResponseModel)
async def main_endpoint():
    query = articles_model.articles.select().where(
        articles_model.articles.c.status == 2
    )
    return ResponseModel(
        items=await db.database.fetch_all(query),
    )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.