fastgenerateapi 1.2.13__tar.gz → 1.2.14__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.
Files changed (122) hide show
  1. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/PKG-INFO +1 -1
  2. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/__init__.py +7 -0
  3. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/__version__.py +1 -1
  4. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/base_view.py +16 -1
  5. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/delete_filter_view.py +14 -7
  6. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/get_all_view.py +75 -50
  7. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/get_relation_view.py +22 -29
  8. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/get_tree_view.py +1 -1
  9. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/dbmodel_mixin.py +27 -0
  10. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/response_mixin.py +4 -5
  11. fastgenerateapi-1.2.14/fastgenerateapi/api_view/mixin/tool_mixin.py +49 -0
  12. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/utils/pdf_util.py +4 -6
  13. fastgenerateapi-1.2.14/fastgenerateapi/api_view/mixin/utils/xlsx_util.py +320 -0
  14. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/switch_view.py +4 -6
  15. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/filter_controller.py +2 -3
  16. fastgenerateapi-1.2.14/fastgenerateapi/deps/__init__.py +13 -0
  17. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/deps/filter_params_deps.py +28 -0
  18. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/deps/tree_params_deps.py +0 -1
  19. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/example/models.py +2 -2
  20. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/example/schemas.py +14 -18
  21. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/example/views.py +14 -24
  22. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/fastapi_utils/param_utils.py +5 -10
  23. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/validator.py +6 -6
  24. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/pydantic_utils/base_model.py +45 -5
  25. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/common_function.py +2 -2
  26. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/response_factory.py +14 -1
  27. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/app_settings.py +5 -7
  28. fastgenerateapi-1.2.14/fastgenerateapi/utils/__init__.py +1 -0
  29. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/str_util.py +10 -2
  30. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi.egg-info/PKG-INFO +1 -1
  31. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi.egg-info/SOURCES.txt +0 -2
  32. fastgenerateapi-1.2.13/fastgenerateapi/api_view/mixin/tool_mixin.py +0 -17
  33. fastgenerateapi-1.2.13/fastgenerateapi/api_view/mixin/utils/xlsx_util.py +0 -336
  34. fastgenerateapi-1.2.13/fastgenerateapi/api_view/sql_get_view.py +0 -142
  35. fastgenerateapi-1.2.13/fastgenerateapi/deps/__init__.py +0 -14
  36. fastgenerateapi-1.2.13/fastgenerateapi/deps/paginator_deps.py +0 -73
  37. fastgenerateapi-1.2.13/fastgenerateapi/validator/__init__.py +0 -0
  38. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/LICENSE +0 -0
  39. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/README.md +0 -0
  40. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/__init__.py +0 -0
  41. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/api_view.py +0 -0
  42. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/create_view.py +0 -0
  43. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/delete_tree_view.py +0 -0
  44. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/delete_view.py +0 -0
  45. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/get_one_view.py +0 -0
  46. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/__init__.py +0 -0
  47. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/base_mixin.py +0 -0
  48. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/get_mixin.py +0 -0
  49. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/save_mixin.py +0 -0
  50. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/utils/__init__.py +0 -0
  51. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/utils/docx_util.py +0 -0
  52. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/utils/file_util.py +0 -0
  53. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/mixin/utils/zip_util.py +0 -0
  54. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/update_relation_view.py +0 -0
  55. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/api_view/update_view.py +0 -0
  56. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/cache/__init__.py +0 -0
  57. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/cache/cache_decorator.py +0 -0
  58. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/cache/key_builder.py +0 -0
  59. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/channel/__init__.py +0 -0
  60. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/channel/connection_manager.py +0 -0
  61. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/channel/consumer.py +0 -0
  62. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/channel/websocket_view.py +0 -0
  63. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/__init__.py +0 -0
  64. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/router_controller.py +0 -0
  65. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/rpc_controller.py +0 -0
  66. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/search_controller.py +0 -0
  67. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/controller/ws_controller.py +0 -0
  68. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/data_type/__init__.py +0 -0
  69. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/data_type/data_type.py +0 -0
  70. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/data_type/mysql_data_type.py +0 -0
  71. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/example/__init__.py +0 -0
  72. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/example/routers.py +0 -0
  73. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/fastapi_utils/__init__.py +0 -0
  74. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/fastapi_utils/all.py +0 -0
  75. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/fastapi_utils/response_utils.py +0 -0
  76. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/fastapi_utils/tortoise_utils.py +0 -0
  77. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/model/__init__.py +0 -0
  78. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/model/base_model.py +0 -0
  79. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/__init__.py +0 -0
  80. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/aes_field.py +0 -0
  81. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/enum_field.py +0 -0
  82. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/pk_field.py +0 -0
  83. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/pwd_field.py +0 -0
  84. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/my_fields/soft_delete_field.py +0 -0
  85. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/pydantic_utils/__init__.py +0 -0
  86. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/pydantic_utils/base_settings.py +0 -0
  87. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/pydantic_utils/json_encoders.py +0 -0
  88. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/__init__.py +0 -0
  89. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/common_schema_factory.py +0 -0
  90. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/create_schema_factory.py +0 -0
  91. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/filter_schema_factory.py +0 -0
  92. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/get_all_schema_factory.py +0 -0
  93. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/get_one_schema_factory.py +0 -0
  94. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/get_relation_schema_factory.py +0 -0
  95. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/get_tree_schema_factory.py +0 -0
  96. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py +0 -0
  97. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/schemas_factory/update_schema_factory.py +0 -0
  98. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/__init__.py +0 -0
  99. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/all_settings.py +0 -0
  100. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/db_settings.py +0 -0
  101. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/etcd_settings.py +0 -0
  102. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/file_settings.py +0 -0
  103. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/jwt_settings.py +0 -0
  104. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/otlp_settings.py +0 -0
  105. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/redis_settings.py +0 -0
  106. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/sms_settings.py +0 -0
  107. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/settings/system_settings.py +0 -0
  108. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/aes.py +0 -0
  109. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/auto_discover.py +0 -0
  110. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/exception.py +0 -0
  111. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/file_utils.py +0 -0
  112. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/pwd_utils.py +0 -0
  113. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/ramdom_utils.py +0 -0
  114. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/snowflake.py +0 -0
  115. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/utils/swagger_to_js.py +0 -0
  116. {fastgenerateapi-1.2.13/fastgenerateapi/utils → fastgenerateapi-1.2.14/fastgenerateapi/validator}/__init__.py +0 -0
  117. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi/validator/validator.py +0 -0
  118. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi.egg-info/dependency_links.txt +0 -0
  119. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/fastgenerateapi.egg-info/top_level.txt +0 -0
  120. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/script/__init__.py +0 -0
  121. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/setup.cfg +0 -0
  122. {fastgenerateapi-1.2.13 → fastgenerateapi-1.2.14}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastgenerateapi
3
- Version: 1.2.13
3
+ Version: 1.2.14
4
4
  Summary: FastAPIView Class View
5
5
  Author: ShiLiang
6
6
  Author-email: 2509144896@qq.com
@@ -27,3 +27,10 @@ from fastgenerateapi.channel.consumer import Consumer
27
27
  # 模型相关类
28
28
  from fastgenerateapi.pydantic_utils.base_model import model_config, BaseModel, IdList
29
29
 
30
+ # 工具相关
31
+ from fastgenerateapi.api_view.mixin.utils.docx_util import DocxUtil
32
+ from fastgenerateapi.api_view.mixin.utils.file_util import FileUtil
33
+ from fastgenerateapi.api_view.mixin.utils.pdf_util import PdfUtil
34
+ from fastgenerateapi.api_view.mixin.utils.xlsx_util import XlsxUtil
35
+ from fastgenerateapi.api_view.mixin.utils.zip_util import ZipUtil
36
+
@@ -8,7 +8,7 @@
8
8
  # d8888P
9
9
 
10
10
 
11
- VERSION = (1, 2, 13)
11
+ VERSION = (1, 2, 14)
12
12
 
13
13
  __version__ = '.'.join(map(str, VERSION))
14
14
 
@@ -24,7 +24,7 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
24
24
 
25
25
  prefix: Optional[str] = None # 路由追加后缀
26
26
  model_class: Optional[Type[Model]] = None # 数据库模型
27
- prefetch_related_fields: Union[None, dict] = None
27
+ prefetch_related_fields: Optional[dict] = None
28
28
  is_with_prefetch: Optional[bool] = False
29
29
  response_schema: Optional[Type[BaseModel]] = None # 通用返回序列化
30
30
  dependencies: Optional[Sequence[params.Depends]] = None
@@ -149,6 +149,8 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
149
149
  model_class: Type[Model],
150
150
  model: Union[Model, None] = None,
151
151
  check_ignore_error_fields: List[str] = None,
152
+ error_format: Optional[str] = None,
153
+ error_value_list: Optional[List[str]] = None,
152
154
  ):
153
155
  """
154
156
  校验模型中设置了 唯一索引和联合唯一索引 的字段
@@ -156,6 +158,8 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
156
158
  :param model_class: 数据库模型
157
159
  :param model: 修改前的数据,用于判断是否修改了字段,当唯一字段与数据data_dict一致时,不会做校验
158
160
  :param check_ignore_error_fields: 错误提示忽略字段,会合并类上的字段
161
+ :param error_format: 错误格式,例如: "错误:输入年龄 '{}' 无效!合法范围是 {}-{} 岁"
162
+ :param error_value_list: 错误字段列表 ,例如:[input_age, min_age, max_age]
159
163
  :return:
160
164
  """
161
165
  check_unique_fields = self._get_unique_fields(model_class)
@@ -193,16 +197,27 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
193
197
  is_equal = False
194
198
  description_fields.append(unique_together_field)
195
199
  filter_fields[unique_together_field] = unique_together_field_value
200
+ elif unique_together_field == settings.app_settings.WHETHER_DELETE_FIELD:
201
+ if settings.app_settings.DELETE_FIELD_TYPE == "time":
202
+ filter_fields[unique_together_field] = 0
203
+ else:
204
+ filter_fields[unique_together_field] = True
196
205
  if is_equal:
197
206
  continue
198
207
 
199
208
  if await model_class.filter(**filter_fields).first():
209
+ if error_format and error_value_list:
210
+ return self.error(
211
+ status_code=422,
212
+ msg=error_format.format(*[data_dict[k] for k in error_value_list])
213
+ )
200
214
  if settings.app_settings.WHETHER_DELETE_FIELD in description_fields:
201
215
  description_fields.remove(settings.app_settings.WHETHER_DELETE_FIELD)
202
216
  for ignore_error_field in ignore_error_field_list:
203
217
  if ignore_error_field in description_fields:
204
218
  description_fields.remove(ignore_error_field)
205
219
  return self.error(
220
+ status_code=422,
206
221
  msg=f"{self.get_field_description(model_class, description_fields)}已存在相同值:{[filter_fields.get(field) for field in description_fields]}"
207
222
  )
208
223
 
@@ -11,8 +11,9 @@ from tortoise.transactions import atomic
11
11
 
12
12
  from fastgenerateapi.api_view.base_view import BaseView
13
13
  from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
14
- from fastgenerateapi.deps import filter_params_deps
15
- from fastgenerateapi.schemas_factory import response_factory, get_one_schema_factory
14
+ from fastgenerateapi.deps.filter_params_deps import filter_json_deps
15
+ from fastgenerateapi.pydantic_utils.base_model import IdList, SearchPydantic
16
+ from fastgenerateapi.schemas_factory import response_factory
16
17
  from fastgenerateapi.settings.all_settings import settings
17
18
 
18
19
 
@@ -28,22 +29,28 @@ class DeleteFilterView(BaseView):
28
29
  """
29
30
 
30
31
  @atomic()
31
- async def destroy_filter(self, search: str, filters: dict, *args, **kwargs):
32
+ async def destroy_filter(self, search: str, request_data, filters: dict, *args, **kwargs):
32
33
  queryset = await self.get_queryset(search=search, filters=filters, *args, **kwargs)
33
-
34
+ queryset = await self.get_del_filter_queryset(queryset, request_data=request_data, *args, **kwargs)
34
35
  await self.delete_queryset(queryset)
35
36
 
36
37
  return
37
38
 
39
+ async def get_del_filter_queryset(self, queryset, request_data, *args, **kwargs):
40
+ queryset = queryset.filter(id__in=request_data.id_list)
41
+ return queryset
42
+
38
43
  def _delete_filter_decorator(self, *args: Any, **kwargs: Any) -> DecoratedCallable:
39
44
  async def route(
40
45
  request: Request,
41
- search: str = Query(default="", description="搜索"),
42
- filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
46
+ search: SearchPydantic,
47
+ request_data: IdList,
48
+ filters: dict = Depends(filter_json_deps(model_class=self.model_class, fields=self.filter_fields)),
43
49
  token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
44
50
  ) -> JSONResponse:
45
51
  data = await self.destroy_filter(
46
- search=search,
52
+ search=search.search,
53
+ request_data=request_data,
47
54
  filters=filters,
48
55
  request=request,
49
56
  token=token,
@@ -19,10 +19,10 @@ from fastgenerateapi.cache.cache_decorator import get_all_cache_decorator
19
19
  from fastgenerateapi.cache.key_builder import generate_key_builder
20
20
  from fastgenerateapi.controller import SearchController, BaseFilter, FilterController
21
21
  from fastgenerateapi.data_type.data_type import DEPENDENCIES, PYDANTIC_SCHEMA
22
- from fastgenerateapi.deps import paginator_deps, filter_params_deps
22
+ from fastgenerateapi.deps import filter_params_deps
23
23
  from fastgenerateapi.deps.filter_params_deps import search_params_deps, extra_filter_params_deps
24
- from fastgenerateapi.schemas_factory import get_all_schema_factory, get_page_schema_factory, get_one_schema_factory, \
25
- response_factory
24
+ from fastgenerateapi.pydantic_utils.base_model import PagePydantic
25
+ from fastgenerateapi.schemas_factory import get_all_schema_factory, get_page_schema_factory, response_factory
26
26
  from fastgenerateapi.schemas_factory.get_all_schema_factory import get_list_schema_factory, hasattr_get_all_schema
27
27
  from fastgenerateapi.settings.all_settings import settings
28
28
 
@@ -58,7 +58,11 @@ class GetAllView(BaseView, GetMixin):
58
58
  async def get_all(self, search: Optional[str], filters: dict, *args, **kwargs):
59
59
  queryset = await self.get_queryset(search=search, filters=filters, *args, **kwargs)
60
60
 
61
- return await self.pagination_data(queryset=queryset, *args, **kwargs)
61
+ return await self.get_page_data(
62
+ queryset=queryset,
63
+ prefetch_related_fields=self.prefetch_related_fields,
64
+ *args, **kwargs
65
+ )
62
66
 
63
67
  async def get_queryset(self, search: Optional[str], filters: dict, *args, **kwargs) -> QuerySet:
64
68
  """
@@ -89,73 +93,94 @@ class GetAllView(BaseView, GetMixin):
89
93
  """
90
94
  return model
91
95
 
92
- async def pagination_data(
96
+ async def get_queryset_data(
93
97
  self,
94
98
  queryset: QuerySet,
95
- paginator=None,
96
99
  schema: Type[BaseModel] = None,
97
- name: str = "", # 当使用fields时,需要输入名称用于自动生成schema
98
- fields: List[Union[str, tuple]] = None,
99
- *args, **kwargs
100
+ paginator: Optional[PagePydantic] = PagePydantic(),
101
+ prefetch_related_fields: Optional[dict] = None,
102
+ *args, **kwargs,
100
103
  ):
101
-
102
- data_list = []
103
- if paginator is None or getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == \
104
- settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
104
+ """
105
+ 通用分页函数,获取对应的数据,和分页统计
106
+ :param queryset:
107
+ :param paginator:
108
+ :param schema:
109
+ :param prefetch_related_fields:
110
+ :param args:
111
+ :param kwargs:
112
+ :return:
113
+ """
114
+ count = None
115
+ if paginator.no_page:
105
116
  model_list = await queryset.all()
106
117
  else:
107
118
  count = await queryset.count()
108
- current_num = getattr(paginator, settings.app_settings.CURRENT_PAGE_FIELD)
109
- page_size = getattr(paginator, settings.app_settings.PAGE_SIZE_FIELD)
110
- queryset = queryset.offset(cast(int, (current_num - 1) * page_size))
111
- model_list = await queryset.limit(page_size)
119
+ queryset = queryset.offset(cast(int, (paginator.page - 1) * paginator.page_size))
120
+ model_list = await queryset.limit(paginator.page_size)
112
121
 
122
+ data_list = []
113
123
  for model in model_list:
114
-
115
- await self.setattr_model(model, prefetch_related_fields=self.prefetch_related_fields, *args, **kwargs)
116
-
117
- # await self.setattr_model_rpc(self.rpc_class, model, self.rpc_param)
124
+ await self.setattr_model(model, prefetch_related_fields=prefetch_related_fields, *args, **kwargs)
118
125
  model = await self.set_get_model(model, *args, **kwargs)
119
126
  model = await self.set_get_all_model(model, *args, **kwargs)
120
127
 
121
128
  if schema:
122
- data_list.append(schema.from_orm(model))
123
- elif fields:
124
- data_list.append(await self.getattr_model(model=model, fields=fields))
129
+ data_list.append(schema.model_validate(model))
125
130
  else:
126
- data_list.append(self.get_all_schema.from_orm(model))
127
-
128
- if paginator is None or getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == \
129
- settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
130
- if schema or fields:
131
- return get_list_schema_factory(schema, name)(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
132
- return self.get_list_schema(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
133
- if schema or fields:
134
- return get_page_schema_factory(schema, name)(**{
135
- settings.app_settings.CURRENT_PAGE_FIELD: current_num,
136
- settings.app_settings.PAGE_SIZE_FIELD: page_size,
137
- settings.app_settings.TOTAL_SIZE_FIELD: count,
131
+ data_list.append(self.get_all_schema.model_validate(model))
132
+
133
+ return data_list, count
134
+
135
+ def get_page_schema(self, data_list, count = None, schema: Type[BaseModel] = None, paginator: Optional[PagePydantic] = None, *args, **kwargs):
136
+ """
137
+ 返回列表结果
138
+ :param data_list:
139
+ :param count:
140
+ :param schema: 当使用自定义列表时使用,默认列表的get_all_schema
141
+ :param paginator:
142
+ :param args:
143
+ :param kwargs: 自定义列表时,传schema或fields
144
+ :return:
145
+ """
146
+ if paginator.no_page:
147
+ page_schema = get_list_schema_factory(schema) if schema else self.get_all_list_schema
148
+ else:
149
+ page_schema = get_page_schema_factory(schema) if schema else self.get_all_page_schema
150
+
151
+ return page_schema(
152
+ **paginator.model_dump(by_alias=True),
153
+ **{
138
154
  settings.app_settings.LIST_RESPONSE_FIELD: data_list,
139
- })
140
- return self.get_page_schema(**{
141
- settings.app_settings.CURRENT_PAGE_FIELD: current_num,
142
- settings.app_settings.PAGE_SIZE_FIELD: page_size,
143
- settings.app_settings.TOTAL_SIZE_FIELD: count,
144
- settings.app_settings.LIST_RESPONSE_FIELD: data_list,
145
- })
155
+ settings.app_settings.TOTAL_SIZE_FIELD: count,
156
+ }
157
+ )
146
158
 
147
- def get_page_list(self, page_result: BaseModel):
148
- return getattr(page_result, settings.app_settings.LIST_RESPONSE_FIELD, [])
159
+ async def get_page_data(
160
+ self,
161
+ queryset: QuerySet,
162
+ *args, **kwargs,
163
+ ):
164
+ """
165
+ 通用分页,获取序列化后的值
166
+ :param queryset:
167
+ :param args:
168
+ :param kwargs: 其他参数 schema, paginator, prefetch_related_fields
169
+ :return:
170
+ """
171
+ data_list, count = await self.get_queryset_data(queryset=queryset,*args, **kwargs)
172
+ res = self.get_page_schema(data_list, count, *args, **kwargs)
173
+ return res
149
174
 
150
175
  def _get_all_decorator(self, *args: Any, **kwargs: Any) -> DecoratedCallable:
151
176
  @get_all_cache_decorator(cache(expire=settings.app_settings.CACHE_GET_ALL_SECONDS, coder=JsonCoder,
152
177
  key_builder=generate_key_builder))
153
178
  async def route(
154
179
  request: Request,
155
- paginator=Depends(paginator_deps()),
180
+ paginator: PagePydantic = Depends(),
156
181
  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,
158
- schema=self.filter_schema)),
182
+ filters: dict = Depends(filter_params_deps(
183
+ model_class=self.model_class, fields=self.filter_fields, schema=self.filter_schema)),
159
184
  extra_filters: dict = Depends(extra_filter_params_deps(schema=self.extra_filter_schema)),
160
185
  token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
161
186
  ) -> JSONResponse:
@@ -198,8 +223,8 @@ class GetAllView(BaseView, GetMixin):
198
223
  self.get_all_schema = get_all_schema_factory(self.model_class, extra_include=get_all_schema_include)
199
224
  else:
200
225
  self.get_all_schema = self.get_response_schema()
201
- self.get_page_schema = get_page_schema_factory(self.get_all_schema)
202
- self.get_list_schema = get_list_schema_factory(self.get_all_schema)
226
+ self.get_all_page_schema = get_page_schema_factory(self.get_all_schema)
227
+ self.get_all_list_schema = get_list_schema_factory(self.get_all_schema)
203
228
  self.get_all_response_schema_factory = response_factory(self.get_page_schema, name="GetPage")
204
229
  if not self.get_all_summary:
205
230
  doc = self.get_all.__doc__
@@ -14,7 +14,9 @@ from tortoise.queryset import QuerySet
14
14
  from fastgenerateapi.api_view.base_view import BaseView
15
15
  from fastgenerateapi.controller import SearchController, BaseFilter, FilterController
16
16
  from fastgenerateapi.data_type.data_type import DEPENDENCIES
17
- from fastgenerateapi.deps import paginator_deps, filter_params_deps
17
+ from fastgenerateapi.deps import filter_params_deps
18
+ from fastgenerateapi.deps.filter_params_deps import search_params_deps
19
+ from fastgenerateapi.pydantic_utils.base_model import PagePydantic
18
20
  from fastgenerateapi.schemas_factory import get_page_schema_factory, response_factory
19
21
  from fastgenerateapi.schemas_factory.get_all_schema_factory import get_list_schema_factory
20
22
  from fastgenerateapi.schemas_factory.get_relation_schema_factory import get_relation_schema_factory
@@ -54,13 +56,13 @@ class GetRelationView(BaseView):
54
56
  relation_order_by_fields: 多对多关联表排序对应字段
55
57
  """
56
58
 
57
- async def get_relation(self, pk: str, search: str, filters: dict, relation_filters: dict, *args, **kwargs):
59
+ async def get_relation(self, pk: str, search: Optional[str], filters: dict, relation_filters: dict, *args, **kwargs):
58
60
  relation_queryset = await self.get_relation_queryset(filters=relation_filters, *args, **kwargs)
59
61
  id_list = relation_queryset.filter(Q(**{self.path_id_name: pk})).values_list(self.relation_id_name, flat=True)
60
62
 
61
63
  queryset = await self.get_queryset(search=search, filters=filters, *args, **kwargs)
62
64
 
63
- return await self.pagination_data(queryset=queryset, id_list=id_list, *args, **kwargs)
65
+ return await self.get_tree_data(queryset=queryset, id_list=id_list, *args, **kwargs)
64
66
 
65
67
  async def get_relation_queryset(self, filters: dict, *args, **kwargs) -> QuerySet:
66
68
  """
@@ -104,61 +106,52 @@ class GetRelationView(BaseView):
104
106
  """
105
107
  return model
106
108
 
107
- async def pagination_data(
109
+ async def get_tree_data(
108
110
  self,
109
111
  queryset: QuerySet,
110
112
  id_list,
111
- paginator,
113
+ paginator: Optional[PagePydantic] = PagePydantic(),
112
114
  fields: List[Union[str, tuple]] = None,
113
115
  *args, **kwargs
114
116
  ) -> Union[dict, str, None, BaseModel]:
115
117
 
116
118
  data_list = []
117
- if getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
119
+ if paginator.no_page:
118
120
  model_list = await queryset.filter(id__in=id_list).all()
119
121
  else:
120
- current_num = getattr(paginator, settings.app_settings.CURRENT_PAGE_FIELD)
121
- page_size = getattr(paginator, settings.app_settings.PAGE_SIZE_FIELD)
122
122
  if self.relation_order_by_fields:
123
- id_list = id_list[cast(int, (current_num - 1) * page_size): page_size]
123
+ id_list = id_list[cast(int, (paginator.page - 1) * paginator.page_size): paginator.page_size]
124
124
  queryset = queryset.filter(id__in=id_list)
125
125
  count = await queryset.count()
126
126
  if self.relation_order_by_fields:
127
127
  model_list = await queryset
128
128
  else:
129
- queryset = queryset.offset(cast(int, (current_num - 1) * page_size))
130
- model_list = await queryset.limit(page_size)
129
+ queryset = queryset.offset(cast(int, (paginator.page - 1) * paginator.page_size))
130
+ model_list = await queryset.limit(paginator.page_size)
131
131
 
132
132
  for model in model_list:
133
-
134
133
  await self.setattr_model(model, prefetch_related_fields=self.prefetch_related_fields, *args, **kwargs)
135
-
136
- # await self.setattr_model_rpc(self.rpc_class, model, self.rpc_param)
137
134
  await self.set_get_relation_model(model)
135
+ data_list.append(self.get_relation_schema.model_validate(model))
138
136
 
139
- if fields:
140
- data_list.append(await self.getattr_model(model=model, fields=fields))
141
- else:
142
- data_list.append(self.get_relation_schema.from_orm(model))
143
-
144
- if getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
137
+ if paginator.no_page:
145
138
  return self.get_relation_list_schema(**{
146
139
  settings.app_settings.LIST_RESPONSE_FIELD: data_list,
147
140
  })
148
-
149
- return self.get_relation_page_schema(**{
150
- settings.app_settings.CURRENT_PAGE_FIELD: current_num,
151
- settings.app_settings.PAGE_SIZE_FIELD: page_size,
152
- settings.app_settings.TOTAL_SIZE_FIELD: count,
153
- settings.app_settings.LIST_RESPONSE_FIELD: data_list,
154
- })
141
+ return self.get_relation_page_schema(
142
+ **paginator.model_dump(by_alias=True),
143
+ **{
144
+ settings.app_settings.TOTAL_SIZE_FIELD: count,
145
+ settings.app_settings.LIST_RESPONSE_FIELD: data_list,
146
+ }
147
+ )
155
148
 
156
149
  def _get_relation_decorator(self, *args: Any, **kwargs: Any) -> DecoratedCallable:
157
150
  async def route(
158
151
  pk: str,
159
152
  request: Request,
160
- paginator=Depends(paginator_deps()),
161
- search: str = Query(default="", description="搜索"),
153
+ paginator: PagePydantic = Depends(),
154
+ search: Optional[str] = Depends(search_params_deps(self.search_fields)),
162
155
  filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
163
156
  relation_filters: dict = Depends(
164
157
  filter_params_deps(model_class=self.relation_model_class, fields=self.relation_filter_fields)),
@@ -23,7 +23,7 @@ from fastgenerateapi.api_view.base_view import BaseView
23
23
  from fastgenerateapi.api_view.mixin.get_mixin import GetMixin
24
24
  from fastgenerateapi.controller import SearchController, BaseFilter, FilterController
25
25
  from fastgenerateapi.data_type.data_type import DEPENDENCIES
26
- from fastgenerateapi.deps import paginator_deps, filter_params_deps
26
+ from fastgenerateapi.deps import filter_params_deps
27
27
  from fastgenerateapi.deps.tree_params_deps import tree_params_deps
28
28
  from fastgenerateapi.schemas_factory import get_one_schema_factory, response_factory
29
29
  from fastgenerateapi.schemas_factory.get_tree_schema_factory import get_tree_schema_factory
@@ -116,3 +116,30 @@ class DBModelMixin:
116
116
  except:
117
117
  return model_class
118
118
 
119
+ # ############################### 枚举相关方法 ###############################
120
+ @classmethod
121
+ def get_enum_index_by_model(cls, value, model_class, filed):
122
+ """
123
+ 查找枚举的返回值
124
+ :param value:
125
+ :param model_class:
126
+ :param filed:
127
+ :return: 找不到返回-1
128
+ """
129
+ model_field_info = model_class._meta.fields_map[filed]
130
+
131
+ return cls.get_enum_index(value, model_field_info.enum_list, model_field_info.start_num)
132
+
133
+ @classmethod
134
+ def get_enum_index(cls, value, enum_list: List[any], start_num=0) -> int:
135
+ """
136
+ 查找枚举的返回值
137
+ :param value: 枚举值
138
+ :param enum_list: 枚举列表
139
+ :param start_num:
140
+ :return: 找不到返回-1
141
+ """
142
+ try:
143
+ return start_num + enum_list.index(value)
144
+ except Exception as e:
145
+ return -1
@@ -5,7 +5,6 @@ from urllib.parse import quote
5
5
 
6
6
  from fastapi import HTTPException
7
7
  from fastapi.encoders import jsonable_encoder
8
- from pydantic import BaseModel
9
8
 
10
9
  from fastgenerateapi.settings.all_settings import settings
11
10
  from starlette.background import BackgroundTask
@@ -93,7 +92,7 @@ class ResponseMixin:
93
92
  @staticmethod
94
93
  def stream(
95
94
  bytes_io: BytesIO,
96
- file_name: Optional[str] = None,
95
+ filename: Optional[str] = None,
97
96
  media_type: Optional[str] = None,
98
97
  is_xlsx: Optional[bool] = None,
99
98
  is_docx: Optional[bool] = None,
@@ -102,7 +101,7 @@ class ResponseMixin:
102
101
  """
103
102
 
104
103
  :param bytes_io: io.BytesIO()
105
- :param file_name: 文件名称
104
+ :param filename: 文件名称
106
105
  :param media_type: 优先度大于其他参数
107
106
  :param is_xlsx: 自动设置media_type
108
107
  :param is_docx: 自动设置media_type
@@ -118,8 +117,8 @@ class ResponseMixin:
118
117
  elif is_pdf:
119
118
  media_type = "application/pdf"
120
119
  headers = {}
121
- if file_name:
122
- headers["Content-Disposition"] = f"attachment; filename={quote(file_name, safe='/:?=&')}"
120
+ if filename:
121
+ headers["Content-Disposition"] = f"attachment; filename={quote(filename, safe='/:?=&')}"
123
122
  return StreamingResponse(
124
123
  bytes_io,
125
124
  media_type= media_type,
@@ -0,0 +1,49 @@
1
+ from typing import Type, Optional, Dict, List
2
+
3
+ from pydantic.fields import FieldInfo
4
+
5
+ from fastgenerateapi.data_type.data_type import T
6
+
7
+ class ToolMixin:
8
+
9
+ @staticmethod
10
+ def reserve_dict(data: dict) -> dict:
11
+ """
12
+ 字典key,value互转
13
+ """
14
+ result = {}
15
+ for key, val in data.items():
16
+ result[val] = key
17
+ return result
18
+
19
+ @staticmethod
20
+ def get_schema_alise_to_name(schema: Optional[Type[T]]) -> Dict[str, str]:
21
+ """
22
+ 返回 alias 对 name 的字典
23
+ :param schema:
24
+ :return:
25
+ """
26
+ alias_dict = {}
27
+ if schema and hasattr(schema, "model_fields"):
28
+ for field, info in schema.model_fields.items():
29
+ alias_dict[info.alias or field] = field
30
+
31
+ return alias_dict
32
+
33
+ @staticmethod
34
+ def get_schema_alise_to_field_info(schema: Optional[Type[T]]) -> Dict[str, FieldInfo]:
35
+ """
36
+ 返回 alias 对 FieldInfo 的字典
37
+ :param schema:
38
+ :return:
39
+ """
40
+ alias_dict = {}
41
+ if schema and hasattr(schema, "model_fields"):
42
+ for field, info in schema.model_fields.items():
43
+ if info.alias:
44
+ alias_dict[info.alias] = info
45
+ alias_dict[field] = info
46
+
47
+ return alias_dict
48
+
49
+
@@ -1,6 +1,6 @@
1
1
  import importlib
2
2
  import io
3
- from typing import List, Union, Tuple
3
+ from typing import List, Union, Tuple, Optional
4
4
 
5
5
  from starlette.responses import StreamingResponse
6
6
  from tortoise.models import Model
@@ -17,7 +17,7 @@ class PdfUtil:
17
17
  model: Model,
18
18
  fields_list: List[List[Union[str, Tuple[str]]]],
19
19
  data: List[List[str]],
20
- # rpc_param: Union[Dict[str, Dict[str, List[str]]], Type[RPCParam], None] = None,
20
+ filename: Optional[str] = '导出文件.xlsx',
21
21
  font: str = "msyh",
22
22
  font_path: str = None,
23
23
  modules: str = "fpdf"
@@ -49,15 +49,13 @@ class PdfUtil:
49
49
  for field in fields:
50
50
  if type(field) == tuple:
51
51
  fields_data.append(field[0])
52
- model_data = await BaseView.getattr_model(model_single_obj, fields_data)
53
- # model_data = await self.setattr_model_rpc(self.model_class, model_data, rpc_param)
54
52
  for fields in fields_list:
55
53
  cell_width = 180 / len(fields)
56
54
  for field in fields:
57
55
  if type(field) == str:
58
56
  msg = f"{field[1]}"
59
57
  else:
60
- msg = f"{field[1]} {getattr(model_data, field[0]) if getattr(model_data, field[0]) else ''}"
58
+ msg = f"{field[1]} {getattr(model_single_obj, field[0]) if getattr(model_single_obj, field[0]) else ''}"
61
59
  pdf.cell(cell_width, 8, msg)
62
60
  pdf.ln(10)
63
61
 
@@ -70,7 +68,7 @@ class PdfUtil:
70
68
  byte_string = pdf.output(dest="S").encode('latin-1')
71
69
  bytes_io = io.BytesIO(byte_string)
72
70
 
73
- return ResponseMixin.stream(bytes_io, is_pdf=True)
71
+ return ResponseMixin.stream(bytes_io, filename=filename, is_pdf=True)
74
72
 
75
73
 
76
74