fastgenerateapi 1.2.10__tar.gz → 1.2.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/PKG-INFO +1 -1
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/__version__.py +1 -1
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/base_view.py +10 -1
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/get_all_view.py +7 -3
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/get_one_view.py +2 -13
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/update_view.py +2 -2
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/common_function.py +40 -5
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/common_schema_factory.py +4 -4
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/create_schema_factory.py +28 -2
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/get_all_schema_factory.py +24 -24
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/get_one_schema_factory.py +32 -25
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/get_relation_schema_factory.py +25 -25
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/get_tree_schema_factory.py +0 -77
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/update_schema_factory.py +30 -4
- fastgenerateapi-1.2.12/fastgenerateapi/validator/__init__.py +0 -0
- fastgenerateapi-1.2.12/fastgenerateapi/validator/validator.py +61 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi.egg-info/PKG-INFO +1 -1
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi.egg-info/SOURCES.txt +2 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/LICENSE +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/README.md +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/api_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/create_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/delete_filter_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/delete_tree_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/delete_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/get_relation_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/get_tree_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/base_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/dbmodel_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/get_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/response_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/save_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/tool_mixin.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/docx_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/file_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/pdf_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/xlsx_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/zip_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/sql_get_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/switch_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/update_relation_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/cache/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/cache/cache_decorator.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/cache/key_builder.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/channel/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/channel/connection_manager.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/channel/consumer.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/channel/websocket_view.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/filter_controller.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/router_controller.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/rpc_controller.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/search_controller.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/ws_controller.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/data_type/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/data_type/data_type.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/data_type/mysql_data_type.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/deps/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/deps/filter_params_deps.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/deps/paginator_deps.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/deps/tree_params_deps.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/example/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/example/models.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/example/routers.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/example/schemas.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/example/views.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/all.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/param_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/response_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/tortoise_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/model/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/model/base_model.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/aes_field.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/enum_field.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/pk_field.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/pwd_field.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/soft_delete_field.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/validator.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/base_model.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/base_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/json_encoders.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/filter_schema_factory.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/response_factory.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/all_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/app_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/db_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/etcd_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/file_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/jwt_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/otlp_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/redis_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/sms_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/system_settings.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/aes.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/auto_discover.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/exception.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/file_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/pwd_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/ramdom_utils.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/snowflake.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/str_util.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/utils/swagger_to_js.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi.egg-info/dependency_links.txt +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi.egg-info/top_level.txt +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/script/__init__.py +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/setup.cfg +0 -0
- {fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/setup.py +0 -0
|
@@ -220,7 +220,16 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
|
|
|
220
220
|
:return:
|
|
221
221
|
"""
|
|
222
222
|
if not self.response_schema:
|
|
223
|
-
|
|
223
|
+
get_one_schema_include = []
|
|
224
|
+
if self.is_with_prefetch and self.prefetch_related_fields:
|
|
225
|
+
for key, value in self.prefetch_related_fields.items():
|
|
226
|
+
if value and type(value) in [list, tuple, set]:
|
|
227
|
+
for val in value:
|
|
228
|
+
val_str = val
|
|
229
|
+
if type(val) in [list, tuple, set]:
|
|
230
|
+
val_str = val[0]
|
|
231
|
+
get_one_schema_include.append(key + "__" + val_str)
|
|
232
|
+
self.response_schema = get_one_schema_factory(self.model_class, extra_include=get_one_schema_include)
|
|
224
233
|
|
|
225
234
|
return self.response_schema
|
|
226
235
|
|
|
@@ -152,9 +152,10 @@ class GetAllView(BaseView, GetMixin):
|
|
|
152
152
|
key_builder=generate_key_builder))
|
|
153
153
|
async def route(
|
|
154
154
|
request: Request,
|
|
155
|
-
paginator
|
|
155
|
+
paginator=Depends(paginator_deps()),
|
|
156
156
|
search: Optional[str] = Depends(search_params_deps(self.search_fields)),
|
|
157
|
-
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields,
|
|
157
|
+
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields,
|
|
158
|
+
schema=self.filter_schema)),
|
|
158
159
|
extra_filters: dict = Depends(extra_filter_params_deps(schema=self.extra_filter_schema)),
|
|
159
160
|
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
160
161
|
) -> JSONResponse:
|
|
@@ -193,7 +194,10 @@ class GetAllView(BaseView, GetMixin):
|
|
|
193
194
|
if type(val) in [list, tuple, set]:
|
|
194
195
|
val_str = val[0]
|
|
195
196
|
get_all_schema_include.append(key + "__" + val_str)
|
|
196
|
-
|
|
197
|
+
if hasattr_get_all_schema(self.model_class) or get_all_schema_include:
|
|
198
|
+
self.get_all_schema = get_all_schema_factory(self.model_class, extra_include=get_all_schema_include)
|
|
199
|
+
else:
|
|
200
|
+
self.get_all_schema = self.get_response_schema()
|
|
197
201
|
self.get_page_schema = get_page_schema_factory(self.get_all_schema)
|
|
198
202
|
self.get_list_schema = get_list_schema_factory(self.get_all_schema)
|
|
199
203
|
self.get_all_response_schema_factory = response_factory(self.get_page_schema, name="GetPage")
|
|
@@ -75,19 +75,8 @@ class GetOneView(BaseView, GetMixin):
|
|
|
75
75
|
if func_type != inspect._empty and func_type is not None:
|
|
76
76
|
self.get_one_schema = func_type
|
|
77
77
|
if not self.get_one_schema:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
for key, value in self.prefetch_related_fields.items():
|
|
81
|
-
if value and type(value) in [list, tuple, set]:
|
|
82
|
-
for val in value:
|
|
83
|
-
val_str = val
|
|
84
|
-
if type(val) in [list, tuple, set]:
|
|
85
|
-
val_str = val[0]
|
|
86
|
-
get_one_schema_include.append(key + "__" + val_str)
|
|
87
|
-
self.get_one_schema = get_one_schema_factory(
|
|
88
|
-
model_class=self.model_class,
|
|
89
|
-
extra_include=get_one_schema_include
|
|
90
|
-
)
|
|
78
|
+
self.get_one_schema = self.get_response_schema()
|
|
79
|
+
|
|
91
80
|
self.get_one_response_schema_factory = response_factory(self.get_one_schema, name="GetOne")
|
|
92
81
|
if not self.get_one_summary:
|
|
93
82
|
doc = self.get_one.__doc__
|
|
@@ -59,8 +59,8 @@ class UpdateView(BaseView, SaveMixin):
|
|
|
59
59
|
async def set_update_model(self, model: Model, data_dict: dict, *args, **kwargs) -> Model:
|
|
60
60
|
"""
|
|
61
61
|
在数据模型校验前后修改值:
|
|
62
|
-
-
|
|
63
|
-
-
|
|
62
|
+
- 这里修改将不做唯一字段校验
|
|
63
|
+
- 可用于例如租户id等全局修改,或者字段变更记录等
|
|
64
64
|
data_dict.update({
|
|
65
65
|
"user_id": request.user.id,
|
|
66
66
|
})
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/common_function.py
RENAMED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from typing import Type, Optional, Union, List
|
|
3
|
+
from typing import Type, Optional, Union, List, Callable
|
|
4
4
|
|
|
5
|
+
from fastapi import HTTPException
|
|
5
6
|
from pydantic import field_validator, model_validator
|
|
6
7
|
from pydantic.fields import FieldInfo
|
|
7
8
|
from tortoise import Model
|
|
8
9
|
|
|
9
10
|
from fastgenerateapi.api_view.mixin.dbmodel_mixin import DBModelMixin
|
|
10
|
-
from fastgenerateapi.pydantic_utils.base_model import alias_generator
|
|
11
|
+
from fastgenerateapi.pydantic_utils.base_model import alias_generator, BaseModel
|
|
11
12
|
from fastgenerateapi.settings.all_settings import settings
|
|
12
13
|
|
|
13
14
|
|
|
@@ -77,11 +78,16 @@ def get_field_info_from_model_class(model_class: Type[Model], field: str, descri
|
|
|
77
78
|
return Optional[str], FieldInfo(default=None, description=f"{field}")
|
|
78
79
|
return get_field_info(value, description=description)
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
split_left_field = field.split("__", maxsplit=1)[0]
|
|
82
|
+
field_info = model_class._meta.fields_map.get(split_left_field)
|
|
81
83
|
if field_info:
|
|
82
84
|
description += field_info.description or ""
|
|
85
|
+
elif split_left_field.endswith("_id"):
|
|
86
|
+
field_info = model_class._meta.fields_map.get(split_left_field.removesuffix("_id"))
|
|
87
|
+
if field_info:
|
|
88
|
+
description += field_info.description or ""
|
|
83
89
|
|
|
84
|
-
model_class = DBModelMixin._get_foreign_key_relation_class(model_class,
|
|
90
|
+
model_class = DBModelMixin._get_foreign_key_relation_class(model_class, split_left_field)
|
|
85
91
|
|
|
86
92
|
return get_field_info_from_model_class(model_class, field.split("__", maxsplit=1)[1], description)
|
|
87
93
|
|
|
@@ -103,7 +109,7 @@ def get_dict_from_pydanticmeta(model_class: Type[Model], data: Union[list, tuple
|
|
|
103
109
|
if len(field) == 2:
|
|
104
110
|
if isinstance(field[1], str):
|
|
105
111
|
key_field = field[1]
|
|
106
|
-
|
|
112
|
+
elif isinstance(field[1], FieldInfo):
|
|
107
113
|
field_info = field[1]
|
|
108
114
|
else:
|
|
109
115
|
field_type = field[1]
|
|
@@ -160,6 +166,35 @@ def get_validate_dict_from_fields(fields_info: dict) -> dict:
|
|
|
160
166
|
return validator_dict
|
|
161
167
|
|
|
162
168
|
|
|
169
|
+
class FieldValidateInfo(BaseModel):
|
|
170
|
+
name: str
|
|
171
|
+
is_required: bool
|
|
172
|
+
description: str
|
|
173
|
+
func: Callable
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def get_field_validate_dict(infos: List[FieldValidateInfo]) -> dict:
|
|
177
|
+
"""
|
|
178
|
+
字段做校验
|
|
179
|
+
:param infos:
|
|
180
|
+
:return:
|
|
181
|
+
"""
|
|
182
|
+
if not infos:
|
|
183
|
+
return {}
|
|
184
|
+
|
|
185
|
+
def _func(i: FieldValidateInfo):
|
|
186
|
+
def func(cls, value):
|
|
187
|
+
is_empty = value is None or value == ''
|
|
188
|
+
if i.is_required and is_empty:
|
|
189
|
+
raise HTTPException(status_code=422, detail=i.description+"不能为空")
|
|
190
|
+
if not is_empty and not i.func(value):
|
|
191
|
+
raise HTTPException(status_code=422, detail=i.description+"校验不通过")
|
|
192
|
+
return value
|
|
193
|
+
return func
|
|
194
|
+
|
|
195
|
+
return {"check_"+info.name: field_validator(info.name)(_func(info)) for info in infos}
|
|
196
|
+
|
|
197
|
+
|
|
163
198
|
def get_model_validate_text_to_list(fields: Optional[List[str]]) -> dict:
|
|
164
199
|
"""
|
|
165
200
|
详情列表用于返回
|
|
@@ -31,18 +31,18 @@ def common_schema_factory(
|
|
|
31
31
|
exclude_fields.update(["id", "created_at", "modified_at", "updated_at"])
|
|
32
32
|
if include:
|
|
33
33
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
34
|
-
all_fields_info
|
|
34
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
35
35
|
include_fields.update(include_fields_dict.keys())
|
|
36
36
|
else:
|
|
37
37
|
if hasattr(model_class, "PydanticMeta"):
|
|
38
38
|
if pydantic_meta_include:
|
|
39
39
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, pydantic_meta_include)
|
|
40
|
-
all_fields_info
|
|
40
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
41
41
|
include_fields.update(include_fields_dict.keys())
|
|
42
42
|
else:
|
|
43
43
|
if hasattr(model_class.PydanticMeta, "include"):
|
|
44
44
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, model_class.PydanticMeta.include)
|
|
45
|
-
all_fields_info
|
|
45
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
46
46
|
include_fields.update(include_fields_dict.keys())
|
|
47
47
|
else:
|
|
48
48
|
include_fields.update(all_fields_info.keys())
|
|
@@ -53,7 +53,7 @@ def common_schema_factory(
|
|
|
53
53
|
|
|
54
54
|
if extra_include:
|
|
55
55
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, extra_include)
|
|
56
|
-
all_fields_info
|
|
56
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
57
57
|
include_fields.update(include_fields_dict.keys())
|
|
58
58
|
if exclude:
|
|
59
59
|
exclude_fields.update(exclude)
|
|
@@ -8,7 +8,7 @@ from tortoise import Model
|
|
|
8
8
|
|
|
9
9
|
from fastgenerateapi.data_type.data_type import T
|
|
10
10
|
from fastgenerateapi.schemas_factory.common_function import get_dict_from_model_fields, get_dict_from_pydanticmeta, \
|
|
11
|
-
get_validate_dict_from_fields, get_model_validate_list_to_text
|
|
11
|
+
get_validate_dict_from_fields, get_model_validate_list_to_text, FieldValidateInfo, get_field_validate_dict
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def create_schema_factory(
|
|
@@ -23,6 +23,8 @@ def create_schema_factory(
|
|
|
23
23
|
pydantic_meta_save_exclude: Optional[bool] = True,
|
|
24
24
|
pydantic_meta_create_include: Optional[bool] = True,
|
|
25
25
|
pydantic_meta_create_exclude: Optional[bool] = True,
|
|
26
|
+
pydantic_meta_save_validate: Optional[bool] = True,
|
|
27
|
+
pydantic_meta_create_validate: Optional[bool] = True,
|
|
26
28
|
pydantic_meta_text_to_list: Optional[bool] = True,
|
|
27
29
|
name: Optional[str] = None
|
|
28
30
|
) -> Type[T]:
|
|
@@ -36,6 +38,8 @@ def create_schema_factory(
|
|
|
36
38
|
- save_exclude: 增改通用,指定排除字段
|
|
37
39
|
- create_include: 增使用,额外添加字段
|
|
38
40
|
- create_exclude: 增使用,指定排除字段
|
|
41
|
+
- save_validate: 增改通用,指定字段做校验
|
|
42
|
+
- create_validate: 增使用,指定字段做校验
|
|
39
43
|
|
|
40
44
|
逻辑顺序:合并所有include和exclude,排除include下包含的exclude字段
|
|
41
45
|
|
|
@@ -65,14 +69,17 @@ def create_schema_factory(
|
|
|
65
69
|
("item_id_list", List[str], FieldInfo(description="多对多关联id列表")),
|
|
66
70
|
]
|
|
67
71
|
save_exclude = ["ignore_field"]
|
|
72
|
+
save_validate = [("phone", phone_validate), ("id_card", id_card_validate)]
|
|
68
73
|
create_include = ["create_user"]
|
|
69
74
|
create_exclude = []
|
|
75
|
+
create_validate = []
|
|
70
76
|
"""
|
|
71
77
|
all_fields_info = get_dict_from_model_fields(model_class)
|
|
72
78
|
|
|
73
79
|
include_fields = set()
|
|
74
80
|
exclude_fields = set()
|
|
75
81
|
text_to_list_fields = set()
|
|
82
|
+
validate_field_info = []
|
|
76
83
|
if include:
|
|
77
84
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
78
85
|
all_fields_info.update(include_fields_dict)
|
|
@@ -104,6 +111,24 @@ def create_schema_factory(
|
|
|
104
111
|
exclude_fields.update(model_class.PydanticMeta.save_exclude)
|
|
105
112
|
if pydantic_meta_create_exclude and hasattr(model_class.PydanticMeta, "create_exclude"):
|
|
106
113
|
exclude_fields.update(model_class.PydanticMeta.create_exclude)
|
|
114
|
+
if pydantic_meta_save_validate and hasattr(model_class.PydanticMeta, "save_validate"):
|
|
115
|
+
for validate in model_class.PydanticMeta.save_validate:
|
|
116
|
+
file_type, file_info = all_fields_info.get(validate[0])
|
|
117
|
+
validate_field_info.append(FieldValidateInfo(
|
|
118
|
+
name=validate[0],
|
|
119
|
+
is_required=file_info.is_required(),
|
|
120
|
+
description=file_info.description,
|
|
121
|
+
func=validate[1],
|
|
122
|
+
))
|
|
123
|
+
if pydantic_meta_create_validate and hasattr(model_class.PydanticMeta, "create_validate"):
|
|
124
|
+
for validate in model_class.PydanticMeta.create_validate:
|
|
125
|
+
file_type, file_info = all_fields_info.get(validate[0])
|
|
126
|
+
validate_field_info.append(FieldValidateInfo(
|
|
127
|
+
name=validate[0],
|
|
128
|
+
is_required=file_info.is_required(),
|
|
129
|
+
description=file_info.description,
|
|
130
|
+
func=validate[1],
|
|
131
|
+
))
|
|
107
132
|
if pydantic_meta_text_to_list and hasattr(model_class.PydanticMeta, "text_to_list"):
|
|
108
133
|
text_to_list_fields = getattr(model_class.PydanticMeta, "text_to_list")
|
|
109
134
|
for field in text_to_list_fields:
|
|
@@ -136,12 +161,13 @@ def create_schema_factory(
|
|
|
136
161
|
schema_name = name if name else model_class.__name__ + "CreateSchema"
|
|
137
162
|
schema_field_dict = {field: all_fields_info[field] for field in all_fields}
|
|
138
163
|
validators_dict = get_validate_dict_from_fields(schema_field_dict)
|
|
164
|
+
field_validators = get_field_validate_dict(validate_field_info)
|
|
139
165
|
text_to_list_validators_dict = get_model_validate_list_to_text(text_to_list_fields)
|
|
140
166
|
schema: Type[T] = create_model(
|
|
141
167
|
schema_name,
|
|
142
168
|
**schema_field_dict,
|
|
143
169
|
__config__=model_config,
|
|
144
|
-
__validators__={**validators_dict, **text_to_list_validators_dict},
|
|
170
|
+
__validators__={**validators_dict, **field_validators, **text_to_list_validators_dict},
|
|
145
171
|
)
|
|
146
172
|
return schema
|
|
147
173
|
|
|
@@ -91,7 +91,7 @@ def get_all_schema_factory(
|
|
|
91
91
|
text_to_list_fields = set()
|
|
92
92
|
if include:
|
|
93
93
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
94
|
-
all_fields_info
|
|
94
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
95
95
|
include_fields.update(include_fields_dict.keys())
|
|
96
96
|
else:
|
|
97
97
|
if hasattr(model_class, "PydanticMeta"):
|
|
@@ -131,29 +131,29 @@ def get_all_schema_factory(
|
|
|
131
131
|
else:
|
|
132
132
|
include_fields.update(all_fields_info.keys())
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
134
|
+
if extra_include:
|
|
135
|
+
include_fields_dict = get_dict_from_pydanticmeta(model_class, extra_include)
|
|
136
|
+
all_fields_info.update(include_fields_dict)
|
|
137
|
+
include_fields.update(include_fields_dict.keys())
|
|
138
|
+
if exclude:
|
|
139
|
+
exclude_fields.update(exclude)
|
|
140
|
+
|
|
141
|
+
all_fields = include_fields.difference(exclude_fields)
|
|
142
|
+
if settings.app_settings.GET_EXCLUDE_ACTIVE_VALUE:
|
|
143
|
+
try:
|
|
144
|
+
all_fields.remove(settings.app_settings.WHETHER_DELETE_FIELD)
|
|
145
|
+
except Exception:
|
|
146
|
+
...
|
|
147
|
+
|
|
148
|
+
schema_name = name if name else model_class.__name__ + "GetAllSchema"
|
|
149
|
+
text_to_list_validators_dict = get_model_validate_text_to_list(text_to_list_fields)
|
|
150
|
+
schema: Type[T] = create_model(
|
|
151
|
+
schema_name,
|
|
152
|
+
**{field: all_fields_info[field] for field in all_fields},
|
|
153
|
+
__config__=model_config,
|
|
154
|
+
__validators__={**text_to_list_validators_dict},
|
|
155
|
+
)
|
|
156
|
+
return schema
|
|
157
157
|
|
|
158
158
|
|
|
159
159
|
def get_list_schema_factory(schema_cls: Type[T] = None, response_field: Optional[str] = None, name: str = "") -> Type[T]:
|
|
@@ -12,6 +12,13 @@ from fastgenerateapi.pydantic_utils.base_model import model_config
|
|
|
12
12
|
from fastgenerateapi.schemas_factory.common_function import get_dict_from_model_fields, get_dict_from_pydanticmeta, \
|
|
13
13
|
get_model_validate_text_to_list
|
|
14
14
|
|
|
15
|
+
def hasattr_get_one_schema(model_class: Type[Model],):
|
|
16
|
+
if not hasattr(model_class, "PydanticMeta"):
|
|
17
|
+
return False
|
|
18
|
+
if hasattr(model_class.PydanticMeta, "get_one_include") or hasattr(model_class.PydanticMeta, "get_one_exclude"):
|
|
19
|
+
return True
|
|
20
|
+
return False
|
|
21
|
+
|
|
15
22
|
|
|
16
23
|
def get_one_schema_factory(
|
|
17
24
|
model_class: Type[Model],
|
|
@@ -82,7 +89,7 @@ def get_one_schema_factory(
|
|
|
82
89
|
text_to_list_fields = set()
|
|
83
90
|
if include:
|
|
84
91
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
85
|
-
all_fields_info
|
|
92
|
+
all_fields_info = {**include_fields_dict, **all_fields_info}
|
|
86
93
|
include_fields.update(include_fields_dict.keys())
|
|
87
94
|
else:
|
|
88
95
|
if hasattr(model_class, "PydanticMeta"):
|
|
@@ -122,30 +129,30 @@ def get_one_schema_factory(
|
|
|
122
129
|
else:
|
|
123
130
|
include_fields.update(all_fields_info.keys())
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
132
|
+
if extra_include:
|
|
133
|
+
include_fields_dict = get_dict_from_pydanticmeta(model_class, extra_include)
|
|
134
|
+
all_fields_info.update(include_fields_dict)
|
|
135
|
+
include_fields.update(include_fields_dict.keys())
|
|
136
|
+
if exclude:
|
|
137
|
+
exclude_fields.update(exclude)
|
|
138
|
+
|
|
139
|
+
all_fields = include_fields.difference(exclude_fields)
|
|
140
|
+
|
|
141
|
+
if settings.app_settings.GET_EXCLUDE_ACTIVE_VALUE:
|
|
142
|
+
try:
|
|
143
|
+
all_fields.remove(settings.app_settings.WHETHER_DELETE_FIELD)
|
|
144
|
+
except Exception:
|
|
145
|
+
...
|
|
146
|
+
|
|
147
|
+
schema_name = name if name else model_class.__name__ + "GetOneSchema"
|
|
148
|
+
text_to_list_validators_dict = get_model_validate_text_to_list(text_to_list_fields)
|
|
149
|
+
schema: Type[T] = create_model(
|
|
150
|
+
schema_name,
|
|
151
|
+
**{field: all_fields_info[field] for field in all_fields},
|
|
152
|
+
__config__=model_config,
|
|
153
|
+
__validators__={**text_to_list_validators_dict},
|
|
154
|
+
)
|
|
155
|
+
return schema
|
|
149
156
|
|
|
150
157
|
|
|
151
158
|
|
|
@@ -65,31 +65,31 @@ def get_relation_schema_factory(
|
|
|
65
65
|
else:
|
|
66
66
|
include_fields.update(all_fields_info.keys())
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
68
|
+
if extra_include:
|
|
69
|
+
include_fields_dict = get_dict_from_pydanticmeta(model_class, extra_include)
|
|
70
|
+
all_fields_info.update(include_fields_dict)
|
|
71
|
+
include_fields.update(include_fields_dict.keys())
|
|
72
|
+
if exclude:
|
|
73
|
+
exclude_fields.update(exclude)
|
|
74
|
+
|
|
75
|
+
all_fields = include_fields.difference(exclude_fields)
|
|
76
|
+
|
|
77
|
+
if settings.app_settings.GET_EXCLUDE_ACTIVE_VALUE:
|
|
78
|
+
try:
|
|
79
|
+
all_fields.remove(settings.app_settings.WHETHER_DELETE_FIELD)
|
|
80
|
+
except Exception:
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
schema_name = name if name else model_class.__name__ + "GetRelationSchema"
|
|
84
|
+
text_to_list_validators_dict = get_model_validate_text_to_list(text_to_list_fields)
|
|
85
|
+
schema: Type[T] = create_model(
|
|
86
|
+
schema_name,
|
|
87
|
+
**{field: all_fields_info[field] for field in all_fields},
|
|
88
|
+
__config__=model_config,
|
|
89
|
+
__validators__={**text_to_list_validators_dict},
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return schema
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
|
|
@@ -107,82 +107,5 @@ def get_tree_schema_factory(
|
|
|
107
107
|
return schema
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
# def get_tree_schema_factory(
|
|
111
|
-
# model_class: Type[Model],
|
|
112
|
-
# include: Union[list, tuple, set] = None,
|
|
113
|
-
# extra_include: Union[list, tuple, set] = None,
|
|
114
|
-
# exclude: Union[list, tuple, set] = None,
|
|
115
|
-
# ) -> Optional[Type[T]]:
|
|
116
|
-
# """
|
|
117
|
-
# Is used to create a GetTreeSchema
|
|
118
|
-
# """
|
|
119
|
-
# def get_tree_schema(schema_cls: Optional[Type[T]] = None):
|
|
120
|
-
# all_fields_info: dict = get_dict_from_model_fields(model_class)
|
|
121
|
-
#
|
|
122
|
-
# include_fields = set()
|
|
123
|
-
# exclude_fields = set()
|
|
124
|
-
# if hasattr(model_class, "PydanticMeta"):
|
|
125
|
-
# if hasattr(model_class.PydanticMeta, "get_tree_include"):
|
|
126
|
-
# get_tree_include_fields_dict = get_dict_from_pydanticmeta(model_class, model_class.PydanticMeta.get_tree_include)
|
|
127
|
-
# all_fields_info.update(get_tree_include_fields_dict)
|
|
128
|
-
# include_fields.update(get_tree_include_fields_dict.keys())
|
|
129
|
-
# if hasattr(model_class.PydanticMeta, "include"):
|
|
130
|
-
# include_fields_dict = get_dict_from_pydanticmeta(model_class, model_class.PydanticMeta.include)
|
|
131
|
-
# all_fields_info.update(include_fields_dict)
|
|
132
|
-
# include_fields.update(include_fields_dict.keys())
|
|
133
|
-
# else:
|
|
134
|
-
# include_fields.update(all_fields_info.keys())
|
|
135
|
-
# if hasattr(model_class.PydanticMeta, "get_tree_exclude"):
|
|
136
|
-
# exclude_fields.update(model_class.PydanticMeta.get_tree_exclude)
|
|
137
|
-
# if hasattr(model_class.PydanticMeta, "exclude"):
|
|
138
|
-
# exclude_fields.update(model_class.PydanticMeta.exclude)
|
|
139
|
-
# else:
|
|
140
|
-
# include_fields.update(all_fields_info.keys())
|
|
141
|
-
#
|
|
142
|
-
# if include:
|
|
143
|
-
# include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
144
|
-
# all_fields_info.update(include_fields_dict)
|
|
145
|
-
# include_fields.update(include_fields_dict.keys())
|
|
146
|
-
# if extra_include:
|
|
147
|
-
# include_fields_dict = get_dict_from_pydanticmeta(model_class, extra_include)
|
|
148
|
-
# all_fields_info.update(include_fields_dict)
|
|
149
|
-
# include_fields.update(include_fields_dict.keys())
|
|
150
|
-
# if exclude:
|
|
151
|
-
# exclude_fields.update(exclude)
|
|
152
|
-
#
|
|
153
|
-
# all_fields = include_fields.difference(exclude_fields)
|
|
154
|
-
#
|
|
155
|
-
# if schema_cls:
|
|
156
|
-
# all_fields_info.setdefault(
|
|
157
|
-
# settings.app_settings.DEFAULT_TREE_CHILDREN_FIELD,
|
|
158
|
-
# (Optional[List[Type[schema_cls]]], FieldInfo(default=None, description="子级目录"))
|
|
159
|
-
# )
|
|
160
|
-
# else:
|
|
161
|
-
# all_fields_info.setdefault(
|
|
162
|
-
# settings.app_settings.DEFAULT_TREE_CHILDREN_FIELD,
|
|
163
|
-
# (Optional[list], FieldInfo(default=None, description="子级目录"))
|
|
164
|
-
# )
|
|
165
|
-
# all_fields.add(settings.app_settings.DEFAULT_TREE_CHILDREN_FIELD)
|
|
166
|
-
# if settings.app_settings.GET_EXCLUDE_ACTIVE_VALUE:
|
|
167
|
-
# try:
|
|
168
|
-
# all_fields.remove(settings.app_settings.WHETHER_DELETE_FIELD)
|
|
169
|
-
# except Exception:
|
|
170
|
-
# ...
|
|
171
|
-
#
|
|
172
|
-
# name = model_class.__name__ + "GetTreeSchema"
|
|
173
|
-
# schema: Type[T] = create_model(
|
|
174
|
-
# __model_name=name, **{field: all_fields_info[field] for field in all_fields}, __config__=Config)
|
|
175
|
-
#
|
|
176
|
-
# return schema
|
|
177
|
-
#
|
|
178
|
-
# tree_schema = get_tree_schema()
|
|
179
|
-
# return get_tree_schema(tree_schema)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
110
|
|
|
188
111
|
|
|
@@ -10,7 +10,7 @@ from tortoise import Model
|
|
|
10
10
|
|
|
11
11
|
from fastgenerateapi.data_type.data_type import T
|
|
12
12
|
from fastgenerateapi.schemas_factory.common_function import get_dict_from_model_fields, get_dict_from_pydanticmeta, \
|
|
13
|
-
get_validate_dict_from_fields, get_model_validate_list_to_text
|
|
13
|
+
get_validate_dict_from_fields, get_model_validate_list_to_text, FieldValidateInfo, get_field_validate_dict
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def update_schema_factory(
|
|
@@ -25,6 +25,8 @@ def update_schema_factory(
|
|
|
25
25
|
pydantic_meta_save_exclude: Optional[bool] = True,
|
|
26
26
|
pydantic_meta_update_include: Optional[bool] = True,
|
|
27
27
|
pydantic_meta_update_exclude: Optional[bool] = True,
|
|
28
|
+
pydantic_meta_save_validate: Optional[bool] = True,
|
|
29
|
+
pydantic_meta_update_validate: Optional[bool] = True,
|
|
28
30
|
pydantic_meta_text_to_list: Optional[bool] = True,
|
|
29
31
|
name: Optional[str] = None
|
|
30
32
|
) -> Type[T]:
|
|
@@ -36,8 +38,10 @@ def update_schema_factory(
|
|
|
36
38
|
- exclude: 增改详情列表通用,指定排除字段
|
|
37
39
|
- save_include: 增改通用,额外添加字段
|
|
38
40
|
- save_exclude: 增改通用,指定排除字段
|
|
39
|
-
- update_include:
|
|
40
|
-
- update_exclude:
|
|
41
|
+
- update_include: 改使用,额外添加字段
|
|
42
|
+
- update_exclude: 改使用,指定排除字段
|
|
43
|
+
- save_validate: 增改通用,指定字段做校验
|
|
44
|
+
- update_validate: 改使用,指定字段做校验
|
|
41
45
|
|
|
42
46
|
逻辑顺序:合并所有include和exclude,排除include下包含的exclude字段
|
|
43
47
|
|
|
@@ -67,14 +71,17 @@ def update_schema_factory(
|
|
|
67
71
|
("item_id_list", List[str], FieldInfo(description="多对多关联id列表")),
|
|
68
72
|
]
|
|
69
73
|
save_exclude = ["ignore_field"]
|
|
74
|
+
save_validate = [("phone", phone_validate), ("id_card", id_card_validate)]
|
|
70
75
|
update_include = ["update_user"]
|
|
71
76
|
update_exclude = []
|
|
77
|
+
update_validate = []
|
|
72
78
|
"""
|
|
73
79
|
all_fields_info = get_dict_from_model_fields(model_class)
|
|
74
80
|
|
|
75
81
|
include_fields = set()
|
|
76
82
|
exclude_fields = set()
|
|
77
83
|
text_to_list_fields = set()
|
|
84
|
+
validate_field_info = []
|
|
78
85
|
if include:
|
|
79
86
|
include_fields_dict = get_dict_from_pydanticmeta(model_class, include)
|
|
80
87
|
all_fields_info.update(include_fields_dict)
|
|
@@ -106,6 +113,24 @@ def update_schema_factory(
|
|
|
106
113
|
exclude_fields.update(model_class.PydanticMeta.save_exclude)
|
|
107
114
|
if pydantic_meta_update_exclude and hasattr(model_class.PydanticMeta, "update_exclude"):
|
|
108
115
|
exclude_fields.update(model_class.PydanticMeta.update_exclude)
|
|
116
|
+
if pydantic_meta_save_validate and hasattr(model_class.PydanticMeta, "save_validate"):
|
|
117
|
+
for validate in model_class.PydanticMeta.save_validate:
|
|
118
|
+
file_type, file_info = all_fields_info.get(validate[0])
|
|
119
|
+
validate_field_info.append(FieldValidateInfo(
|
|
120
|
+
name=validate[0],
|
|
121
|
+
is_required=file_info.is_required(),
|
|
122
|
+
description=file_info.description,
|
|
123
|
+
func=validate[1],
|
|
124
|
+
))
|
|
125
|
+
if pydantic_meta_update_validate and hasattr(model_class.PydanticMeta, "update_validate"):
|
|
126
|
+
for validate in model_class.PydanticMeta.create_validate:
|
|
127
|
+
file_type, file_info = all_fields_info.get(validate[0])
|
|
128
|
+
validate_field_info.append(FieldValidateInfo(
|
|
129
|
+
name=validate[0],
|
|
130
|
+
is_required=file_info.is_required(),
|
|
131
|
+
description=file_info.description,
|
|
132
|
+
func=validate[1],
|
|
133
|
+
))
|
|
109
134
|
if pydantic_meta_text_to_list and hasattr(model_class.PydanticMeta, "text_to_list"):
|
|
110
135
|
text_to_list_fields = getattr(model_class.PydanticMeta, "text_to_list")
|
|
111
136
|
for field in text_to_list_fields:
|
|
@@ -138,11 +163,12 @@ def update_schema_factory(
|
|
|
138
163
|
schema_name = name if name else model_class.__name__ + "UpdateSchema"
|
|
139
164
|
schema_field_dict = {field: all_fields_info[field] for field in all_fields}
|
|
140
165
|
validators_dict = get_validate_dict_from_fields(schema_field_dict)
|
|
166
|
+
field_validators = get_field_validate_dict(validate_field_info)
|
|
141
167
|
text_to_list_validators_dict = get_model_validate_list_to_text(text_to_list_fields)
|
|
142
168
|
schema: Type[T] = create_model(
|
|
143
169
|
schema_name,
|
|
144
170
|
**schema_field_dict,
|
|
145
171
|
__config__=model_config,
|
|
146
|
-
__validators__={**validators_dict, **text_to_list_validators_dict},
|
|
172
|
+
__validators__={**validators_dict, **field_validators, **text_to_list_validators_dict},
|
|
147
173
|
)
|
|
148
174
|
return schema
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from datetime import datetime, date
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def phone_validate(phone: Optional[str]) -> bool:
|
|
7
|
+
"""
|
|
8
|
+
手机号码校验
|
|
9
|
+
:param phone:
|
|
10
|
+
:return:
|
|
11
|
+
"""
|
|
12
|
+
if not phone:
|
|
13
|
+
return False
|
|
14
|
+
phone_pattern = re.compile(r'^(?:(?:\+|00)86)?1[3-9]\d{9}$')
|
|
15
|
+
|
|
16
|
+
return phone_pattern.fullmatch(phone) is not None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def id_card_validate(id_card: Optional[str]) -> bool:
|
|
20
|
+
"""
|
|
21
|
+
身份证号码校验
|
|
22
|
+
:param id_card:
|
|
23
|
+
:return:
|
|
24
|
+
"""
|
|
25
|
+
if not id_card or len(id_card) != 18:
|
|
26
|
+
return False
|
|
27
|
+
id_card = id_card.upper()
|
|
28
|
+
if not id_card[:17].isdigit() or id_card[-1] not in '0123456789X':
|
|
29
|
+
return False
|
|
30
|
+
date_of_birth = datetime(
|
|
31
|
+
year=int(id_card[6:10]),
|
|
32
|
+
month=int(id_card[10:12]),
|
|
33
|
+
day=int(id_card[12:14])
|
|
34
|
+
)
|
|
35
|
+
current_date = date.today()
|
|
36
|
+
if date_of_birth > current_date or date_of_birth.year < 1900:
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
|
40
|
+
check_code_map = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}
|
|
41
|
+
|
|
42
|
+
total = sum(int(id_card[i]) * weights[i] for i in range(17))
|
|
43
|
+
|
|
44
|
+
remainder = total % 11
|
|
45
|
+
expected_check_code = check_code_map[remainder]
|
|
46
|
+
return id_card[-1] == expected_check_code
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def email_validate(email: Optional[str]) -> bool:
|
|
50
|
+
"""
|
|
51
|
+
验证邮箱格式合法性(符合RFC 5322简化标准,覆盖99%+日常/开发场景)
|
|
52
|
+
:param email: 待校验的邮箱字符串
|
|
53
|
+
:return: 合法返回True,否则False
|
|
54
|
+
"""
|
|
55
|
+
if not email:
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
email_pattern = r'^[a-zA-Z0-9_%+-]+(?:\.[a-zA-Z0-9_%+-]+)*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
59
|
+
|
|
60
|
+
return re.fullmatch(email_pattern, email) is not None
|
|
61
|
+
|
|
@@ -111,4 +111,6 @@ fastgenerateapi/utils/ramdom_utils.py
|
|
|
111
111
|
fastgenerateapi/utils/snowflake.py
|
|
112
112
|
fastgenerateapi/utils/str_util.py
|
|
113
113
|
fastgenerateapi/utils/swagger_to_js.py
|
|
114
|
+
fastgenerateapi/validator/__init__.py
|
|
115
|
+
fastgenerateapi/validator/validator.py
|
|
114
116
|
script/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/delete_filter_view.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/delete_tree_view.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/get_relation_view.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/__init__.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/base_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/dbmodel_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/get_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/response_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/save_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/tool_mixin.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/__init__.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/docx_util.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/file_util.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/pdf_util.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/xlsx_util.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/mixin/utils/zip_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/api_view/update_relation_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/channel/connection_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/filter_controller.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/router_controller.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/rpc_controller.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/search_controller.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/controller/ws_controller.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/data_type/mysql_data_type.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/deps/filter_params_deps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/param_utils.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/response_utils.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/fastapi_utils/tortoise_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/my_fields/soft_delete_field.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/__init__.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/base_model.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/base_settings.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/pydantic_utils/json_encoders.py
RENAMED
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/schemas_factory/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/redis_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi/settings/system_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastgenerateapi-1.2.10 → fastgenerateapi-1.2.12}/fastgenerateapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|