Просмотр исходного кода

优化查询没有的字段处理

SpringSunYY 4 месяцев назад
Родитель
Сommit
e780960866
2 измененных файлов с 221 добавлено и 199 удалено
  1. 63 45
      ruoyi_common/base/reqparser.py
  2. 158 154
      ruoyi_common/base/schema_vo.py

+ 63 - 45
ruoyi_common/base/reqparser.py

@@ -13,7 +13,7 @@ from ruoyi_common.base.schema_vo import BaseSchemaFactory, QuerySchemaFactory
 
 
 class AbsReqParser(ABC):
-    
+
     @abstractmethod
     def data(self) -> Dict:
         """
@@ -22,7 +22,7 @@ class AbsReqParser(ABC):
         Returns:
             Dict: 请求参数字典
         """
-    
+
     @abstractmethod
     def cast_model(self, bo_model:BaseEntity) -> BaseModel:
         """
@@ -35,7 +35,7 @@ class AbsReqParser(ABC):
         Returns:
             BaseModel: 适配后的模型
         """
-    
+
     @abstractmethod
     def prepare_factory(self, factory:BaseSchemaFactory):
         """
@@ -44,45 +44,45 @@ class AbsReqParser(ABC):
         Args:
             factory (BaseSchemaFactory): 工厂
         """
-    
+
     @abstractmethod
     def prepare(self):
         """
         准备数据
-        """ 
+        """
 
 class BaseReqParser(AbsReqParser):
-    
+
     def data(self) -> Dict:
         pass
-    
+
     def cast_model(self, bo_model:BaseEntity) -> BaseModel:
         pass
-    
+
     def prepare_factory(self, factory:BaseSchemaFactory):
         pass
 
     def prepare(self):
         pass
-    
+
 
 class QueryReqParser(BaseReqParser):
 
     def __init__(self, context:VoValidatorContext):
         self.context = context
         self.extra_model = ExtraModel
-    
+
     def prepare_factory(self, factory: QuerySchemaFactory):
         if factory.extra_model:
             self.extra_model = factory.extra_model
-            
+
     def prepare(self):
         self.criterian_meta = CriterianMeta()
         g.criterian_meta = self.criterian_meta
-    
+
     def validate_request(self) -> Dict:
         return request.args.to_dict()
-    
+
     def data(self) -> Dict:
         data = self.validate_request().copy()
         if self.context.is_page:
@@ -101,16 +101,34 @@ class QueryReqParser(BaseReqParser):
                 self.criterian_meta.extra = extra
             self._remove_model_aliases(data, self.extra_model)
         return data
-    
+
     def cast_model(self, bo_model:BaseEntity) -> BaseModel:
         data = self.data()
-        bo = bo_model.model_validate(data)
+        # 对于查询参数,只保留模型中定义的字段和别名,忽略额外字段
+        # 收集模型中所有字段名和别名
+        model_fields = set()
+        for name, info in bo_model.model_fields.items():
+            model_fields.add(name)
+            # 添加查询别名(camelCase)
+            if hasattr(bo_model, 'model_config') and bo_model.model_config:
+                alias_gen = bo_model.model_config.get('alias_generator')
+                if callable(alias_gen):
+                    model_fields.add(alias_gen(name))
+            # 添加 validation_alias
+            if info.validation_alias:
+                if isinstance(info.validation_alias, str):
+                    model_fields.add(info.validation_alias)
+                elif hasattr(info.validation_alias, 'choices'):
+                    model_fields.update(info.validation_alias.choices)
+        # 过滤掉未定义的字段
+        filtered_data = {k: v for k, v in data.items() if k in model_fields}
+        bo = bo_model.model_validate(filtered_data)
         return bo
 
     def _remove_model_aliases(
-        self,
-        data: Dict[str, str],
-        model_cls: Type[BaseModel]
+            self,
+            data: Dict[str, str],
+            model_cls: Type[BaseModel]
     ) -> None:
         """
         删除已经用于解析的模型字段别名,避免后续模型校验时报额外字段错误
@@ -131,9 +149,9 @@ class QueryReqParser(BaseReqParser):
 
     @staticmethod
     def _field_aliases(
-        name: str,
-        info,
-        populate_by_name: bool
+            name: str,
+            info,
+            populate_by_name: bool
     ) -> Iterable[str]:
         aliases: Set[str] = set()
         if getattr(info, "alias", None):
@@ -148,23 +166,23 @@ class QueryReqParser(BaseReqParser):
         if populate_by_name:
             aliases.add(name)
         return aliases
-    
-    
+
+
 @dataclass
 class PathReqParser(BaseReqParser):
-    
+
     def data(self) -> Dict:
         return request.view_args.copy()
-        
+
 
 @dataclass
 class BodyReqParser(BaseReqParser):
-    
+
     minetype: ClassVar[str] = "application/json"
 
     def __init__(self, context:VoValidatorContext):
         self.context = context
-        
+
     def validate_request(self) -> Dict:
         content_type = request.headers.get("Content-Type", "").lower()
         minetype = content_type.split(";")[0]
@@ -179,7 +197,7 @@ class BodyReqParser(BaseReqParser):
                 description="content-type仅支持application/json"
             )
         return body
-    
+
     def data(self) -> Dict:
         data = self.validate_request().copy()
         return data
@@ -192,12 +210,12 @@ class BodyReqParser(BaseReqParser):
 
 @dataclass
 class FormUrlencodedQueryReqParser(QueryReqParser):
-    
+
     minetype: ClassVar[str] = "application/x-www-form-urlencoded"
-    
+
     def __init__(self, context:VoValidatorContext):
         super().__init__(context)
-    
+
     def validate_request(self) -> Dict:
         content_type = request.headers.get("Content-Type", "").lower()
         minetype = content_type.split(";")[0]
@@ -213,25 +231,25 @@ class FormUrlencodedQueryReqParser(QueryReqParser):
 
 @dataclass
 class DownloadFileQueryReqParser(FormUrlencodedQueryReqParser):
-    
+
     def __init__(self, context:VoValidatorContext):
         super().__init__(context)
 
 
 class FormReqParser(BaseReqParser):
-    
+
     minetype: ClassVar[str] = "multipart/form-data"
-    
+
     def __init__(
-        self, 
-        is_form:bool=True,
-        is_query:bool=False,
-        is_file:bool|None=None,
-        ):
+            self,
+            is_form:bool=True,
+            is_query:bool=False,
+            is_file:bool|None=None,
+    ):
         self.is_form = is_form
         self.is_query = is_query
         self.is_file = is_file
-        
+
     def validate_request(self) -> Dict:
         content_type = request.headers.get("Content-Type", "").lower()
         minetype = content_type.split(";")[0]
@@ -248,22 +266,22 @@ class FormReqParser(BaseReqParser):
                 description="除了{},content-type不支持{}".format(self.minetype,minetype)
             )
         return new_data
-    
+
     def data(self) -> Dict:
         data = self.validate_request()
         return data
 
-    
+
 class UploadFileFormReqParser(FormReqParser):
-    
+
     def validate_request(self) -> Dict:
         return super().validate_request()
 
     def data(self) -> Dict:
         data = self.validate_request()
         return data
-    
-            
+
+
 class StreamReqParser(BaseReqParser):
 
     minetype: ClassVar[str] = "application/octet-stream"

+ 158 - 154
ruoyi_common/base/schema_vo.py

@@ -10,104 +10,103 @@ from pydantic.fields import FieldInfo
 from pydantic_core import PydanticUndefined
 from pydantic import BaseModel
 
-from ruoyi_common.base.model import AllowedExtraModel, BaseEntity, BetOpt, ExtraModel, ExtraOpt, MultiFile, VoAccess, VoValidatorContext
+from ruoyi_common.base.model import AllowedExtraModel, BaseEntity, BetOpt, ExtraModel, ExtraOpt, MultiFile, VoAccess, \
+    VoValidatorContext
 from ruoyi_common.utils.base import DateUtil, get_final_model
 
-
 T = TypeVar("T")
 
 strict_valid_config = ConfigDict(
-    from_attributes = False,
-    alias_generator = to_camel,  
-    frozen = True,
-    extra = "forbid",
-    strict = True,
-    populate_by_name = False,
-    json_encoders = {
+    from_attributes=False,
+    alias_generator=to_camel,
+    frozen=True,
+    extra="forbid",
+    strict=True,
+    populate_by_name=False,
+    json_encoders={
         datetime: lambda v: v.strftime(DateUtil.YYYY_MM_DD_HH_MM_SS)
     },
 )
 
 query_valid_config = ConfigDict(
-    from_attributes = False,
-    alias_generator = to_camel,  
-    frozen = True,
-    extra = "allow",
-    strict = True,
-    populate_by_name = False,
+    from_attributes=False,
+    alias_generator=to_camel,
+    frozen=True,
+    extra="allow",
+    strict=True,
+    populate_by_name=False,
 )
 
 
 def VoField(
-    body=True,
-    query=False,
-    sort=False, 
-    *args, 
-    **kwargs
-    ):
+        body=True,
+        query=False,
+        sort=False,
+        *args,
+        **kwargs
+):
     vo = VoAccess(
         body=body,
         query=query,
         sort=sort,
     )
-    return Field(vo=vo,*args, **kwargs)
-
+    return Field(vo=vo, *args, **kwargs)
 
 
 class AbcFieldFilter(ABC):
-    
-    def filter(self, name:str, info:FieldInfo) -> bool:
+
+    def filter(self, name: str, info: FieldInfo) -> bool:
         """
         过滤字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否过滤
         """
 
 
 class BaseFieldFilter(AbcFieldFilter):
-    
-    def filter(self, name:str, info:FieldInfo) -> bool:
+
+    def filter(self, name: str, info: FieldInfo) -> bool:
         """
         过滤字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否过滤
         """
         return False
-    
-    
+
+
 class VoBodyFieldFilter(BaseFieldFilter):
-    
+
     def __init__(self):
         self.action = "body"
-    
-    def filter(self, name:str, info:FieldInfo) -> bool:
+
+    def filter(self, name: str, info: FieldInfo) -> bool:
         """
         过滤字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否过滤
         """
         default = True
         if info.json_schema_extra:
-            vo_access:VoAccess = info.json_schema_extra.get("vo",default)
+            vo_access: VoAccess = info.json_schema_extra.get("vo", default)
             if vo_access:
-                perm = getattr(vo_access,self.action,default)
+                perm = getattr(vo_access, self.action, default)
                 if perm:
-                    is_required = getattr(vo_access,"body_required",False)
+                    is_required = getattr(vo_access, "body_required", False)
                     if is_required:
                         self.change_to_required(info)
                     else:
@@ -118,23 +117,23 @@ class VoBodyFieldFilter(BaseFieldFilter):
         else:
             flag = default
         return flag
-    
+
     @classmethod
-    def change_to_required(cls, info:FieldInfo):
+    def change_to_required(cls, info: FieldInfo):
         """
         将注解转换为必选项
-        
+
         Args:
             info(FieldInfo): 字段元信息
         """
         info.default = PydanticUndefined
         info.default_factory = None
-    
+
     @classmethod
-    def change_to_optional(cls, info:FieldInfo):
+    def change_to_optional(cls, info: FieldInfo):
         """
         将注解转换为可选项
-        
+
         Args:
             info(FieldInfo): 字段元信息
         """
@@ -143,29 +142,28 @@ class VoBodyFieldFilter(BaseFieldFilter):
 
 
 class VoQueryFieldFilter(BaseFieldFilter):
-    
     extra_opt_cls_list = [BetOpt]
-    
+
     def __init__(self):
         self.action = "query"
-        self.sort_fields:Dict[str,FieldInfo] = {}
-        self.extra_fields:Dict[str,ExtraOpt] = {}
-    
-    def filter(self, name:str, info:FieldInfo) -> bool:
+        self.sort_fields: Dict[str, FieldInfo] = {}
+        self.extra_fields: Dict[str, ExtraOpt] = {}
+
+    def filter(self, name: str, info: FieldInfo) -> bool:
         """
         根据权限信息,重置字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             Tuple[bool,bool]: 是否支持查询,是否支持排序
         """
         default = False
         if info.json_schema_extra:
-            vo_access:VoAccess = info.json_schema_extra.get("vo",False)
-            query_perm = getattr(vo_access,self.action,default)
+            vo_access: VoAccess = info.json_schema_extra.get("vo", False)
+            query_perm = getattr(vo_access, self.action, default)
             for extra_opt_cls in self.extra_opt_cls_list:
                 if isinstance(query_perm, extra_opt_cls):
                     query_perm.name = name
@@ -174,46 +172,45 @@ class VoQueryFieldFilter(BaseFieldFilter):
                     query_perm = False
                 else:
                     continue
-            sort_perm = getattr(vo_access,"sort",default)
+            sort_perm = getattr(vo_access, "sort", default)
             if sort_perm:
                 self.sort_fields[name] = info
             return query_perm
         else:
             return default
-    
+
 
 class AbcSchemaFactory(ABC):
-    
+
     @abstractmethod
-    def validate_annotation(annotation:Type) -> Optional[Type]:
+    def validate_annotation(annotation: Type) -> Optional[Type]:
         """
         检查注解是否有效
-        
-        Args:    
+
+        Args:
             annotation(Type): 注解
-        
+
         Returns:
             Optional[Type]: 合法的类型
         """
         pass
-    
+
 
 class BaseSchemaFactory(AbcSchemaFactory):
-    
     action = "base"
     model_config = query_valid_config
-            
+
     def __init__(self):
         self.field_filter = None
         self.model_suffix = "Vo"
-    
-    def validate_annotation(self, annotation:Type) -> Optional[Type]:
+
+    def validate_annotation(self, annotation: Type) -> Optional[Type]:
         """
         检查注解是否有效
-        
+
         Args:
             annotation(Type): 注解
-        
+
         Returns:
             Optional[Type]: 合法的类型
         """
@@ -223,42 +220,54 @@ class BaseSchemaFactory(AbcSchemaFactory):
             return model
         else:
             return None
-        
-    def rebuild_model(self, model_cls:Type[BaseEntity]) -> Type[BaseEntity]:
+
+    def rebuild_model(self, model_cls: Type[BaseEntity]) -> Type[BaseEntity]:
         """
         从已有模型类,创建新的模型类
-        
+
         Args:
             model_cls: 已有模型类
-        
+
         Returns:
             Type[BaseModel]: 新的模型类
         """
-        
+
         field_definitions = {}
-        for name,info in model_cls.model_fields.items():
-            flag = self.rebuild_field(name,info)
+        for name, info in model_cls.model_fields.items():
+            flag = self.rebuild_field(name, info)
             if flag:
-                field_definitions[name] = info.annotation,info
+                field_definitions[name] = info.annotation, info
         vo_name = model_cls.__name__ + self.action.capitalize() + \
-            self.model_suffix
+                  self.model_suffix
+
+        # 如果是 QuerySchemaFactory,使用 query_valid_config 允许额外字段
+        if hasattr(self, 'action') and self.action == 'query' and hasattr(self, 'model_config'):
+            # 创建一个新的基类,使用 query_valid_config
+            class QueryBaseModel(model_cls):
+                model_config = self.model_config.copy()
+
+            base_class = QueryBaseModel
+        else:
+            base_class = model_cls
 
-        return create_model(
-            vo_name, 
-            __base__= model_cls,
-            __doc__ = model_cls.__doc__, 
-            __module__= model_cls.__module__, 
+        new_model = create_model(
+            vo_name,
+            __base__=base_class,
+            __doc__=model_cls.__doc__,
+            __module__=model_cls.__module__,
             **field_definitions
         )
-    
-    def rebuild_field(self, name:str, info:FieldInfo) -> bool:
+
+        return new_model
+
+    def rebuild_field(self, name: str, info: FieldInfo) -> bool:
         """
         重置字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否支持重置
         """
@@ -266,15 +275,14 @@ class BaseSchemaFactory(AbcSchemaFactory):
 
 
 class BodySchemaFactory(BaseSchemaFactory):
-    
     action = "body"
     model_config = query_valid_config
-    
-    def __init__(self,context:VoValidatorContext):
+
+    def __init__(self, context: VoValidatorContext):
         super().__init__()
         self.context = context
         self.field_filter = VoBodyFieldFilter()
-        
+
     def validate_annotation(self, annotation: Type) -> Optional[Type[BaseModel]]:
         bo_model = get_final_model(annotation)
         if issubclass(bo_model, BaseModel):
@@ -284,38 +292,37 @@ class BodySchemaFactory(BaseSchemaFactory):
             if self.context.include_fields or self.context.exclude_fields:
                 raise Exception(f"注解{annotation.__name__}不是模型,不支持include和exclude请求条件")
             return None
-        
-    def rebuild_field(self, name:str, info:FieldInfo) -> bool:
+
+    def rebuild_field(self, name: str, info: FieldInfo) -> bool:
         """
         重置字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否支持重置
         """
         if self.context.include_fields and \
-            name not in self.context.include_fields:
+                name not in self.context.include_fields:
             return False
         if self.context.exclude_fields and \
-            name in self.context.exclude_fields:
+                name in self.context.exclude_fields:
             return False
-        flag = self.field_filter.filter(name,info)
+        flag = self.field_filter.filter(name, info)
         return flag
 
 
 class QuerySchemaFactory(BaseSchemaFactory):
-    
     action = "query"
     model_config = query_valid_config
-    
+
     def __init__(
-        self,
-        context,
-        extra_strict_forbid=True,
-        extra_allowed_fields:Type[Dict[str,FieldInfo]]=None
+            self,
+            context,
+            extra_strict_forbid=True,
+            extra_allowed_fields: Type[Dict[str, FieldInfo]] = None
     ):
         super().__init__()
         self.context = context
@@ -323,12 +330,13 @@ class QuerySchemaFactory(BaseSchemaFactory):
         self.extra_strict_forbid = extra_strict_forbid
         self.extra_allowed_fields = extra_allowed_fields
         self.extra_model = None
-    
+
     def validate_annotation(self, annotation: Type) -> Optional[Type[BaseEntity]]:
         bo_model = get_final_model(annotation)
         if issubclass(bo_model, BaseEntity):
             updated_model = self.rebuild_model(model_cls=bo_model)
-            self.model_config = annotation.model_config.copy()
+            # 使用 query_valid_config 而不是原模型的配置,允许额外字段
+            self.model_config = self.model_config.copy()
             self._validate_context()
             self.rebuild_extra_model()
             return updated_model
@@ -336,16 +344,16 @@ class QuerySchemaFactory(BaseSchemaFactory):
             if self.context.include_fields or self.context.exclude_fields:
                 raise Exception(f"注解{annotation.__name__}不是模型,不支持include和exclude请求条件")
             return None
-    
+
     def _validate_context(self):
         """
         验证上下文信息
         """
-        for name,info in self.field_filter.sort_fields.items():
-            alias_set = self.get_validate_alias(name,info)
+        for name, info in self.field_filter.sort_fields.items():
+            alias_set = self.get_validate_alias(name, info)
             self.context.include_sort_alias = self.context.include_sort_alias | alias_set
-        
-    def get_validate_alias(self, name:str,info:FieldInfo) -> Set[str]:
+
+    def get_validate_alias(self, name: str, info: FieldInfo) -> Set[str]:
         """
         获取验证别名
 
@@ -370,19 +378,19 @@ class QuerySchemaFactory(BaseSchemaFactory):
                 raise Exception(f"模型字段{name}不支持AliasPath")
             elif isinstance(info.validation_alias, AliasChoices):
                 alias_set = alias_set | \
-                    set(info.validation_alias.choices)
+                            set(info.validation_alias.choices)
         if "populate_by_name" in self.model_config \
-            and self.model_config["populate_by_name"]:
+                and self.model_config["populate_by_name"]:
             alias_set.add(name)
         return alias_set
-    
-    def get_alias_from_config(self,name:str)-> Optional[str]:
+
+    def get_alias_from_config(self, name: str) -> Optional[str]:
         """
         从配置中获取别名
-        
+
         Args:
             name (str): 字段名称
-        
+
         Returns:
             Optional[str]: 别名
         """
@@ -392,34 +400,34 @@ class QuerySchemaFactory(BaseSchemaFactory):
                 alias = generate_alias(name)
                 return alias
             elif isinstance(generate_alias, AliasGenerator):
-                alias,v_alias,s_alias = generate_alias(name)
+                alias, v_alias, s_alias = generate_alias(name)
                 return alias or v_alias
-    
+
     def rebuild_extra_model(self) -> Optional[Type[ExtraModel]]:
         """
         重新构建Extra查询模型
-        
+
         Args:
             fields (Dict[str,ExtraOpt]): 字段元信息
-        
+
         Returns:
             Optional[Type[ExtraModel]]: extra查询模型
         """
         field_defintions = {}
-        for name,opt in self.field_filter.extra_fields.items():
+        for name, opt in self.field_filter.extra_fields.items():
             if isinstance(opt, BetOpt):
-                min_fieldinfo,max_fieldinfo = self.rebuild_bet_opt(name,opt)
-                field_defintions[opt.min] = min_fieldinfo.annotation,min_fieldinfo
-                field_defintions[opt.max] = max_fieldinfo.annotation,max_fieldinfo
+                min_fieldinfo, max_fieldinfo = self.rebuild_bet_opt(name, opt)
+                field_defintions[opt.min] = min_fieldinfo.annotation, min_fieldinfo
+                field_defintions[opt.max] = max_fieldinfo.annotation, max_fieldinfo
             elif isinstance(opt, ExtraOpt):
-                field_defintions[name] = opt.info.annotation,opt.info
+                field_defintions[name] = opt.info.annotation, opt.info
             else:
                 continue
-        
+
         if self.extra_allowed_fields:
-            for name,info in self.extra_allowed_fields.items():
+            for name, info in self.extra_allowed_fields.items():
                 if name not in field_defintions:
-                    field_defintions[name] = info.annotation,info
+                    field_defintions[name] = info.annotation, info
 
         if field_defintions:
             extra_model_cls = ExtraModel if self.extra_strict_forbid else AllowedExtraModel
@@ -428,81 +436,77 @@ class QuerySchemaFactory(BaseSchemaFactory):
                 __base__=extra_model_cls,
                 **field_defintions
             )
-    
-    def rebuild_bet_opt(self, name:str, opt:BetOpt) -> Tuple[FieldInfo,FieldInfo]:
+
+    def rebuild_bet_opt(self, name: str, opt: BetOpt) -> Tuple[FieldInfo, FieldInfo]:
         """
         重新构建BetOpt
-        
+
         Args:
             name (str): 字段名称
             opt (BetOpt): 字段元信息
-        
+
         Returns:
             Tuple[FieldInfo,FieldInfo]: Between查询条件信息
         """
         min_opt = opt.replace(active="min")
         min_fieldinfo = FieldInfo.from_annotation(min_opt.info.annotation)
-        min_fieldinfo.json_schema_extra={"vo_opt":min_opt}
+        min_fieldinfo.json_schema_extra = {"vo_opt": min_opt}
         max_opt = opt.replace(active="max")
         max_fieldinfo = FieldInfo.from_annotation(max_opt.info.annotation)
-        max_fieldinfo.json_schema_extra={"vo_opt":max_opt}
-        return min_fieldinfo,max_fieldinfo
+        max_fieldinfo.json_schema_extra = {"vo_opt": max_opt}
+        return min_fieldinfo, max_fieldinfo
 
-    def rebuild_field(self, name:str, info:FieldInfo) -> bool:
+    def rebuild_field(self, name: str, info: FieldInfo) -> bool:
         """
         重置字段
-        
+
         Args:
             name(str): 字段名称
             info(FieldInfo): 字段元信息
-        
+
         Returns:
             bool: 是否支持重置
         """
         if self.context.include_fields and \
-            name not in self.context.include_fields:
+                name not in self.context.include_fields:
             return False
         if self.context.exclude_fields and \
-            name in self.context.exclude_fields:
+                name in self.context.exclude_fields:
             return False
-        flag = self.field_filter.filter(name,info)
+        flag = self.field_filter.filter(name, info)
         return flag
 
 
 class FormSchemaFactory(AbcSchemaFactory):
-    
     action = "form"
     model_config = strict_valid_config
-    
+
     def validate_annotation(self, annotation: Type[BaseModel]) -> Optional[Type[BaseModel]]:
         pass
 
 
 class PathSchemaFactory(AbcSchemaFactory):
-    
     action = "path"
     model_config = query_valid_config
-    
+
     def validate_annotation(self, annotation: Type[BaseModel]) -> Optional[Type[BaseModel]]:
         pass
-    
+
 
 class ArbitrarySchemaFactory(AbcSchemaFactory):
-    
     model_config = query_valid_config
-    
+
     def __init__(self):
         super().__init__()
         query_valid_config_copy = query_valid_config.copy()
         query_valid_config_copy.update({
-            "arbitrary_types_allowed":True
+            "arbitrary_types_allowed": True
         })
         self.model_config = query_valid_config_copy
-    
+
     def validate_annotation(self, annotation: Type) -> Optional[Type[BaseEntity]]:
         bo_model = get_final_model(annotation)
         if issubclass(bo_model, BaseEntity):
             return bo_model
         else:
             return None
-