Closed shurshilov closed 1 year ago
Hey there, please provide a self contained example that shows your use case and allows me to copy paste and replicate it here, otherwise it's a bit difficult to understand your intention and your problem. ☕
Hello, yes, I solved the problem by changing the frontend. But in principle, such functionality would probably come in handy. Once again, when a request arrives at the endpoint with a filter parameter, say filter={id:1, name:aaa, age:25} naturally encoded in the query string, then it's all easy to extract, BUT some JS libraries send not a filter object, but unpack parameter and it turns out a request of this type www.example.com/myendpoint?id=1&name=aaa&age=25 and it turns out that the parameters are already unpacked and you have to write a little code to validate them. But in my case, I just packed in filter
from fastapi import APIRouter, Depends, Response, Request
from typing import Any, Type, Union, TypeVar
from pydantic import Json
from ..const import LOG
from ..managers.QueryManager import QueryManagerObject
from ..external.auth import (
verify_token_header_auth_bearer_scheme,
header_auth_bearer_scheme,
)
from ..models_orm.base import Model as BaseModel
T = TypeVar("T", bound=BaseModel)
class CRUDRouterGenerator(APIRouter):
Model = None
def __init__(
self,
Model: Type[T],
search_route: bool = True,
create_route: bool = True,
update_route: bool = True,
delete_route: bool = True,
get_route: bool = True,
**kwargs: Any,
) -> None:
self.Model = Model
super().__init__(**kwargs)
if search_route:
self.add_api_route(
f"{self.Model.__route__}",
self.search(),
response_model=list[self.Model],
methods=["GET"],
)
if create_route:
self.add_api_route(f"{Model.__route__}", self.create(), methods=["POST"])
if update_route:
self.add_api_route(
f"{Model.__route__}/{{id}}", self.update(), methods=["PUT"]
)
if delete_route:
self.add_api_route(
f"{Model.__route__}/{{id}}", self.delete(), methods=["DELETE"]
)
if get_route:
self.add_api_route(
f"{Model.__route__}/{{id}}",
self.get(),
methods=["GET"],
response_model=Model,
response_model_exclude_none=True,
)
def search(self, *args: Any, **kwargs: Any) -> callable:
Model = self.Model
async def route(
response: Response,
req: Request,
_end: int = 25,
_order="DESC",
_sort="id",
_start: int = 0,
_filter: Json = None,
):
try:
if _filter:
#do validation
records = await QueryManagerObject.search(
Model,
Model.get_store_fields(),
_end,
_order,
_sort,
_start,
_filter,
)
count_total = await QueryManagerObject.table_len(Model)
response.headers["X-Total-Count"] = str(count_total)
return records
except Exception as e:
LOG.exception(f"Error when {Model.__name__} fetching: {e.__context__}")
return route
Thanks for reporting back and closing the issue 👍
Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.
First Check
Commit to Help
Example Code
Description
I try do that filter sended to query parametrs as field=values work. Its standart REST function for filter data for example in REACT ADMIN and I can catch all query params from request compare it with model fields and if equal that build filter for frontend But i want use dynamicly set all query params in router from model with additional params as sort paginations and other Because describe all params in each router take long time and also i use CRUD generator fast API and its not compatible. just set **Model.dict() not work because need describe annotation also
Operating System
Windows
Operating System Details
No response
FastAPI Version
0.78
Python Version
3.9.1
Additional Context
No response