Files
DjangoAdmin_Flask_EleVue/utils/request.py
T
DjangoAdmin DevandClaude 15f2a5e097 chore: 基线提交(重构前代码快照)
- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等)
- 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb)
- 含后端全部代码:application / extensions / utils / config / migrations
- 含前端 ui/(后续整体迁走)
- 不含根 .env(含密钥,本地保留)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 12:12:06 +08:00

197 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
请求解析工具模块
=============================================================
提供请求数据解析相关的工具函数:
- get_json_data: 从Flask请求中解析JSON数据
- require_json: 装饰器,要求请求必须包含JSON数据
- parse_request_body: 解析请求体JSON数据,返回(data, error)元组
- parse_id_list: 将逗号分隔的ID字符串解析为整数列表
- parse_batch_ids: 从请求体解析批量删除ID数组,校验并转为逗号分隔字符串
- like_escape: 转义SQL LIKE通配符,防止用户输入被当作通配符
- like_contains: 构建安全的LIKE包含查询值
"""
import logging
from functools import wraps
logger = logging.getLogger(__name__)
def get_json_data(required=True, silent=False):
"""
获取请求中的JSON数据
Args:
required: 是否必须获取到JSON数据,默认为True
silent: 是否静默处理错误,默认为False(False时会检查Content-Type)
Returns:
dict: JSON数据,如果获取失败则返回None或空字典
"""
from flask import request
if not silent and not request.is_json:
return None
try:
json_data = request.get_json(silent=silent)
except Exception:
return None
if required and not json_data:
return None
return json_data or {}
def require_json(f):
"""
装饰器:要求请求必须包含JSON数据
Examples:
@require_json
def login():
data = get_json_data()
# 业务逻辑...
"""
@wraps(f)
def decorated_function(*args, **kwargs):
from flask import request
if not request.is_json:
from utils import R
return R.failed(msg="参数格式不正确,请使用JSON格式")
json_data = request.get_json()
if not json_data:
from utils import R
return R.failed(msg="参数不能为空")
request.parsed_json = json_data
return f(*args, **kwargs)
return decorated_function
def parse_request_body():
"""
解析请求体JSON数据
Returns:
tuple: (data, error)
成功时 data 为解析后的字典,error 为 None
失败时 data 为 None,error 为错误描述字符串
"""
try:
data = get_json_data(required=False, silent=True)
if data is None or data == {}:
return None, "参数不能为空"
return data, None
except Exception as e:
logger.error(f"解析请求体异常: {str(e)}")
return None, "参数处理失败"
def parse_id_list(id_str: str, separator: str = ',') -> list:
"""
将逗号分隔的ID字符串解析为整数列表
Args:
id_str: 逗号分隔的ID字符串,如 "1,2,3"
separator: 分隔符,默认为逗号
Returns:
list: 有效的整数ID列表
Example:
>>> parse_id_list("1,2,3")
[1, 2, 3]
>>> parse_id_list("1,2,abc,3")
[1, 2, 3]
"""
if not id_str:
return []
result = []
for item in id_str.split(separator):
item = item.strip()
if item.isdigit():
result.append(int(item))
return result
def parse_batch_ids():
"""
从请求体解析批量删除的ID数组,校验并转为逗号分隔字符串
请求体格式: [1, 2, 3]
Returns:
tuple: (id_str, error_response)
成功时 id_str 为 "1,2,3",error_response 为 None
失败时 id_str 为 None,error_response 为 R.failed 响应
"""
from flask import request
from utils import R
ids = request.get_json()
if not ids or not isinstance(ids, list) or len(ids) == 0:
return None, R.failed("参数错误:ids必须为非空数组")
try:
id_list = [int(id_val) for id_val in ids]
except (ValueError, TypeError):
return None, R.failed("参数错误:数组元素必须为数字")
return ','.join(str(id_val) for id_val in id_list), None
def like_escape(value, escape_char='\\'):
"""
转义SQL LIKE通配符
将用户输入中的 %、_ 和转义字符本身进行转义,
防止用户输入被当作LIKE通配符导致非预期查询结果。
Args:
value: 原始输入值
escape_char: 转义字符,默认为反斜杠
Returns:
str: 转义后的安全字符串
Example:
>>> like_escape('100%')
'100\\%'
>>> like_escape('test_data')
'test\\_data'
"""
escaped = str(value).replace(escape_char, escape_char * 2)
escaped = escaped.replace('%', escape_char + '%')
escaped = escaped.replace('_', escape_char + '_')
return escaped
def like_contains(value, escape_char='\\'):
"""
构建安全的LIKE包含查询值(前后加%)
对用户输入进行通配符转义后,前后添加 % 构建模糊查询值。
配合 SQLAlchemy 的 .like() 方法和 escape 参数使用。
Args:
value: 原始输入值
escape_char: 转义字符,默认为反斜杠
Returns:
str: 构建好的LIKE查询值,如 '%safe_value%'
Example:
>>> # SQLAlchemy 用法
>>> query = query.filter(User.name.like(like_contains(name), escape='\\'))
"""
return f'%{like_escape(value, escape_char)}%'