refactor: P2 core+common 建设(应用工厂/扩展/工具层迁入 src/)
【结构】 - src/core/:database/response/jwt/password/security/redis_client/mail/scheduler - src/common/:base_model/base_db/forms(base_form+fields)/constants/utils - src/models_registry.py:模型聚合器(Flask-Migrate 全量表识别) 【绞杀者 shim】extensions/、utils/、application/constants|forms|models 打兼容转发 【兼容修复】应用工厂抽取至 application/factory.py(P2 前置,P1 已完成) 【基线修复】application/models(25) + middleware(7) 原被嵌套 .gitignore(*) 误排除出版本库,已补入(base_model/base_db 现为 shim,原版在 src/common/) 【登记既有缺陷】 1. flask db CLI 因 .env FLASK_VERSION 与 --version 冲突报错 → Makefile 已加 FLASK_SKIP_DOTENV=1 2. 本机 Redis 未设密码但 REDIS_AUTH=True,/captcha 报 AUTH 错误(环境问题) 【验收】22 模型表全量识别;src/ flake8 零告警;pytest 5 passed;应用启动; /login 表单校验、/user/page 鉴权拦截冒烟正常 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
92130ef070
commit
658ee6d596
+4
-323
@@ -1,327 +1,8 @@
|
||||
"""
|
||||
命名格式转换工具模块
|
||||
兼容 shim(绞杀者迁移期间保留)
|
||||
=============================================================
|
||||
|
||||
提供字符串命名格式之间的转换功能,主要用于数据库字段名(下划线命名)
|
||||
与前端字段名(驼峰命名)之间的转换。
|
||||
|
||||
主要功能:
|
||||
1. 下划线命名 → 驼峰命名
|
||||
2. 驼峰命名 → 下划线命名
|
||||
3. 下划线命名 → 帕斯卡命名(大驼峰)
|
||||
4. 递归转换字典的所有键名
|
||||
命名转换工具已迁移至 src.common.utils.case_converter。
|
||||
本文件仅作兼容转发,最终在 P7(切尾)阶段删除。
|
||||
"""
|
||||
|
||||
|
||||
def convert_camel_case(snake_str):
|
||||
"""
|
||||
将下划线命名转换为驼峰命名
|
||||
|
||||
Args:
|
||||
snake_str: 下划线命名字符串,如 'create_time'
|
||||
|
||||
Returns:
|
||||
驼峰命名字符串,如 'createTime'
|
||||
|
||||
Examples:
|
||||
>>> convert_camel_case('create_time')
|
||||
'createTime'
|
||||
>>> convert_camel_case('user_id')
|
||||
'userId'
|
||||
>>> convert_camel_case('id')
|
||||
'id'
|
||||
>>> convert_camel_case('')
|
||||
''
|
||||
"""
|
||||
if not snake_str:
|
||||
return ''
|
||||
|
||||
components = snake_str.split('_')
|
||||
return components[0] + ''.join(_capitalize_first_letter(x) for x in components[1:])
|
||||
|
||||
|
||||
def convert_snake_case(camel_str):
|
||||
"""
|
||||
将驼峰命名转换为下划线命名
|
||||
|
||||
Args:
|
||||
camel_str: 驼峰命名字符串,如 'createTime'
|
||||
|
||||
Returns:
|
||||
下划线命名字符串,如 'create_time'
|
||||
|
||||
Examples:
|
||||
>>> convert_snake_case('createTime')
|
||||
'create_time'
|
||||
>>> convert_snake_case('userId')
|
||||
'user_id'
|
||||
>>> convert_snake_case('id')
|
||||
'id'
|
||||
>>> convert_snake_case('')
|
||||
''
|
||||
"""
|
||||
if not camel_str:
|
||||
return ''
|
||||
|
||||
result = []
|
||||
for i, char in enumerate(camel_str):
|
||||
if char.isupper() and i > 0:
|
||||
result.append('_')
|
||||
result.append(char.lower())
|
||||
else:
|
||||
result.append(char.lower())
|
||||
|
||||
return ''.join(result)
|
||||
|
||||
|
||||
def convert_pascal_case(snake_str):
|
||||
"""
|
||||
将下划线命名转换为帕斯卡命名(大驼峰)
|
||||
|
||||
Args:
|
||||
snake_str: 下划线命名字符串,如 'create_time'
|
||||
|
||||
Returns:
|
||||
帕斯卡命名字符串,如 'CreateTime'
|
||||
|
||||
Examples:
|
||||
>>> convert_pascal_case('create_time')
|
||||
'CreateTime'
|
||||
>>> convert_pascal_case('user_id')
|
||||
'UserId'
|
||||
>>> convert_pascal_case('')
|
||||
''
|
||||
"""
|
||||
if not snake_str:
|
||||
return ''
|
||||
|
||||
components = snake_str.split('_')
|
||||
return ''.join(_capitalize_first_letter(x) for x in components)
|
||||
|
||||
|
||||
def convert_dict_keys(data, converter=convert_camel_case):
|
||||
"""
|
||||
递归转换字典的所有键名
|
||||
|
||||
Args:
|
||||
data: 需要转换的字典或列表
|
||||
converter: 转换函数,默认为 to_camel_case
|
||||
|
||||
Returns:
|
||||
转换后的字典或列表
|
||||
|
||||
Examples:
|
||||
>>> data = {'create_time': '2024-01-01', 'user_id': 1}
|
||||
>>> convert_dict_keys(data)
|
||||
{'createTime': '2024-01-01', 'userId': 1}
|
||||
|
||||
>>> data = [{'user_name': '张三'}, {'user_name': '李四'}]
|
||||
>>> convert_dict_keys(data)
|
||||
[{'userName': '张三'}, {'userName': '李四'}]
|
||||
"""
|
||||
if isinstance(data, list):
|
||||
return [convert_dict_keys(item, converter) for item in data]
|
||||
|
||||
if isinstance(data, dict):
|
||||
result = {}
|
||||
for key, value in data.items():
|
||||
new_key = converter(key)
|
||||
result[new_key] = convert_dict_keys(value, converter)
|
||||
return result
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def convert_snake_to_camel(data):
|
||||
"""
|
||||
将字典中的下划线命名字段转换为驼峰命名(便捷方法)
|
||||
|
||||
这是 convert_dict_keys 的便捷封装,专门用于数据库字段转前端字段。
|
||||
|
||||
Args:
|
||||
data: 需要转换的字典或列表
|
||||
|
||||
Returns:
|
||||
转换后的字典或列表(所有键名转为驼峰命名)
|
||||
|
||||
Examples:
|
||||
>>> data = {'create_time': '2024-01-01', 'user_id': 1}
|
||||
>>> convert_dict_keys_snake_to_camel(data)
|
||||
{'createTime': '2024-01-01', 'userId': 1}
|
||||
|
||||
>>> data = [{'user_name': '张三'}, {'user_name': '李四'}]
|
||||
>>> convert_dict_keys_snake_to_camel(data)
|
||||
[{'userName': '张三'}, {'userName': '李四'}]
|
||||
"""
|
||||
return convert_dict_keys(data, converter=convert_camel_case)
|
||||
|
||||
|
||||
def convert_camel_to_snake(data):
|
||||
"""
|
||||
将字典中的驼峰命名字段转换为下划线命名(便捷方法)
|
||||
|
||||
这是 convert_dict_keys 的便捷封装,专门用于前端字段转数据库字段。
|
||||
|
||||
Args:
|
||||
data: 需要转换的字典或列表
|
||||
|
||||
Returns:
|
||||
转换后的字典或列表(所有键名转为下划线命名)
|
||||
|
||||
Examples:
|
||||
>>> data = {'createTime': '2024-01-01', 'userId': 1}
|
||||
>>> convert_dict_keys_camel_to_snake(data)
|
||||
{'create_time': '2024-01-01', 'user_id': 1}
|
||||
|
||||
>>> data = [{'userName': '张三'}, {'userName': '李四'}]
|
||||
>>> convert_dict_keys_camel_to_snake(data)
|
||||
[{'user_name': '张三'}, {'user_name': '李四'}]
|
||||
"""
|
||||
return convert_dict_keys(data, converter=convert_snake_case)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 私有方法
|
||||
# ============================================================
|
||||
|
||||
def _capitalize_first_letter(s):
|
||||
"""
|
||||
将字符串的首字母大写,其余字母小写
|
||||
|
||||
Args:
|
||||
s: 输入字符串
|
||||
|
||||
Returns:
|
||||
首字母大写后的字符串
|
||||
|
||||
Examples:
|
||||
>>> _capitalize_first_letter('name')
|
||||
'Name'
|
||||
>>> _capitalize_first_letter('userName')
|
||||
'Username'
|
||||
>>> _capitalize_first_letter('')
|
||||
''
|
||||
"""
|
||||
if not s:
|
||||
return ''
|
||||
return s[0].upper() + s[1:].lower()
|
||||
|
||||
|
||||
def _is_camel_case(s):
|
||||
"""
|
||||
判断字符串是否为驼峰命名格式
|
||||
|
||||
驼峰命名特征:
|
||||
1. 首字母小写
|
||||
2. 不包含下划线
|
||||
3. 包含大写字母(至少一个大写字母)
|
||||
|
||||
Args:
|
||||
s: 输入字符串
|
||||
|
||||
Returns:
|
||||
bool: 是否为驼峰命名格式
|
||||
|
||||
Examples:
|
||||
>>> _is_camel_case('createTime')
|
||||
True
|
||||
>>> _is_camel_case('create_time')
|
||||
False
|
||||
>>> _is_camel_case('id')
|
||||
False
|
||||
"""
|
||||
if not s:
|
||||
return False
|
||||
|
||||
# 首字母必须小写,不包含下划线,且至少有一个大写字母
|
||||
return (s[0].islower() and
|
||||
'_' not in s and
|
||||
any(char.isupper() for char in s))
|
||||
|
||||
|
||||
def _is_snake_case(s):
|
||||
"""
|
||||
判断字符串是否为下划线命名格式
|
||||
|
||||
下划线命名特征:
|
||||
1. 全部小写
|
||||
2. 包含下划线
|
||||
3. 不以_开头,不以_结尾
|
||||
|
||||
Args:
|
||||
s: 输入字符串
|
||||
|
||||
Returns:
|
||||
bool: 是否为下划线命名格式
|
||||
|
||||
Examples:
|
||||
>>> _is_snake_case('create_time')
|
||||
True
|
||||
>>> _is_snake_case('createTime')
|
||||
False
|
||||
>>> _is_snake_case('id')
|
||||
False
|
||||
"""
|
||||
if not s:
|
||||
return False
|
||||
|
||||
# 全部小写,包含下划线,且不以_开头结尾
|
||||
return (s.islower() and
|
||||
'_' in s and
|
||||
not s.startswith('_') and
|
||||
not s.endswith('_'))
|
||||
|
||||
|
||||
def _is_pascal_case(s):
|
||||
"""
|
||||
判断字符串是否为帕斯卡命名格式(大驼峰)
|
||||
|
||||
帕斯卡命名特征:
|
||||
1. 首字母大写
|
||||
2. 不包含下划线
|
||||
3. 至少有一个字母
|
||||
|
||||
Args:
|
||||
s: 输入字符串
|
||||
|
||||
Returns:
|
||||
bool: 是否为帕斯卡命名格式
|
||||
|
||||
Examples:
|
||||
>>> _is_pascal_case('CreateTime')
|
||||
True
|
||||
>>> _is_pascal_case('createTime')
|
||||
False
|
||||
>>> _is_pascal_case('create_time')
|
||||
False
|
||||
"""
|
||||
if not s:
|
||||
return False
|
||||
|
||||
# 首字母大写,不包含下划线
|
||||
return (s[0].isupper() and
|
||||
'_' not in s and
|
||||
any(char.isalpha() for char in s))
|
||||
|
||||
|
||||
def _convert_single_field(field_name, converter=convert_camel_case):
|
||||
"""
|
||||
转换单个字段名
|
||||
|
||||
Args:
|
||||
field_name: 字段名
|
||||
converter: 转换函数,默认为 to_camel_case
|
||||
|
||||
Returns:
|
||||
转换后的字段名
|
||||
|
||||
Examples:
|
||||
>>> _convert_single_field('create_time')
|
||||
'createTime'
|
||||
>>> _convert_single_field('createTime', convert_snake_case)
|
||||
'create_time'
|
||||
"""
|
||||
if not field_name:
|
||||
return ''
|
||||
|
||||
return converter(field_name)
|
||||
from src.common.utils.case_converter import * # noqa: F401,F403
|
||||
|
||||
Reference in New Issue
Block a user