11"""Helper to deal with querystring parameters according to jsonapi specification."""
2+ from collections import defaultdict
23from functools import cached_property
34from typing import (
45 TYPE_CHECKING ,
2223)
2324from starlette .datastructures import QueryParams
2425
26+ from fastapi_jsonapi .api import RoutersJSONAPI
2527from fastapi_jsonapi .exceptions import (
2628 BadRequest ,
27- InvalidField ,
2829 InvalidFilters ,
2930 InvalidInclude ,
3031 InvalidSort ,
3132)
3233from fastapi_jsonapi .schema import (
3334 get_model_field ,
3435 get_relationships ,
35- get_schema_from_type ,
3636)
3737from fastapi_jsonapi .splitter import SPLIT_REL
3838
@@ -97,7 +97,7 @@ def _get_key_values(self, name: str) -> Dict[str, Union[List[str], str]]:
9797 :return: a dict of key / values items
9898 :raises BadRequest: if an error occurred while parsing the querystring.
9999 """
100- results : Dict [ str , Union [ List [ str ], str ]] = {}
100+ results = defaultdict ( set )
101101
102102 for raw_key , value in self .qs .multi_items ():
103103 key = unquote (raw_key )
@@ -109,10 +109,7 @@ def _get_key_values(self, name: str) -> Dict[str, Union[List[str], str]]:
109109 key_end = key .index ("]" )
110110 item_key = key [key_start :key_end ]
111111
112- if "," in value :
113- results .update ({item_key : value .split ("," )})
114- else :
115- results .update ({item_key : value })
112+ results [item_key ].update (value .split ("," ))
116113 except Exception :
117114 msg = "Parse error"
118115 raise BadRequest (msg , parameter = key )
@@ -216,27 +213,28 @@ def fields(self) -> Dict[str, List[str]]:
216213
217214 :raises InvalidField: if result field not in schema.
218215 """
219- if self .request .method != "GET" :
220- msg = "attribute 'fields' allowed only for GET-method"
221- raise InvalidField (msg )
222216 fields = self ._get_key_values ("fields" )
223- for key , value in fields .items ():
224- if not isinstance (value , list ):
225- value = [value ] # noqa: PLW2901
226- fields [key ] = value
217+ for resource_type , field_names in fields .items ():
227218 # TODO: we have registry for models (BaseModel)
228219 # TODO: create `type to schemas` registry
229- schema : Type [BaseModel ] = get_schema_from_type (key , self .app )
230- for field in value :
231- if field not in schema .__fields__ :
232- msg = "{schema} has no attribute {field}" .format (
233- schema = schema .__name__ ,
234- field = field ,
235- )
236- raise InvalidField (msg )
220+
221+ # schema: Type[BaseModel] = get_schema_from_type(key, self.app)
222+ self ._get_schema (resource_type )
223+
224+ # for field_name in field_names:
225+ # if field_name not in schema.__fields__:
226+ # msg = "{schema} has no attribute {field}".format(
227+ # schema=schema.__name__,
228+ # field=field_name,
229+ # )
230+ # raise InvalidField(msg)
237231
238232 return fields
239233
234+ def _get_schema (self , resource_type : str ) -> Type [BaseModel ]:
235+ target_router = RoutersJSONAPI .all_jsonapi_routers [resource_type ]
236+ return target_router .detail_response_schema
237+
240238 def get_sorts (self , schema : Type ["TypeSchema" ]) -> List [Dict [str , str ]]:
241239 """
242240 Return fields to sort by including sort name for SQLAlchemy and row sort parameter for other ORMs.
0 commit comments