169 lines
4.7 KiB
Markdown
169 lines
4.7 KiB
Markdown
# 请求解析工具
|
||
|
||
<!-- Copyright (c) 2021-2026 小蚂蚁云团队 版权所有 -->
|
||
|
||
:::tip 说明
|
||
`utils/common.py` 提供请求数据解析相关的工具函数,核心函数 `parse_request_body()` 用于解析请求体 JSON 数据。这些工具函数在各业务模块中广泛使用。
|
||
:::
|
||
|
||
## parse_request_body
|
||
|
||
解析请求体 JSON 数据,返回 `(data, error)` 元组。这是业务模块中最常用的请求解析函数。
|
||
|
||
```python
|
||
# utils/common.py
|
||
def parse_request_body(request):
|
||
"""
|
||
解析请求体JSON数据
|
||
|
||
Args:
|
||
request: HttpRequest对象
|
||
|
||
Returns:
|
||
tuple: (data, error)
|
||
成功时 data 为解析后的字典,error 为 None
|
||
失败时 data 为 None,error 为错误描述字符串
|
||
"""
|
||
try:
|
||
if not hasattr(request, 'body') or request.body is None:
|
||
return None, None
|
||
if not request.body:
|
||
return None, "参数不能为空"
|
||
|
||
json_data = request.body.decode('utf-8')
|
||
if not json_data:
|
||
return None, "参数不能为空"
|
||
|
||
data = json.loads(json_data)
|
||
return data, None
|
||
|
||
except json.JSONDecodeError as e:
|
||
return None, "参数格式错误"
|
||
except UnicodeDecodeError as e:
|
||
return None, "参数编码错误"
|
||
except Exception as e:
|
||
return None, "参数处理失败"
|
||
```
|
||
|
||
使用示例:
|
||
|
||
```python
|
||
def add_example(request):
|
||
# 解析请求参数
|
||
data, error = parse_request_body(request)
|
||
if error:
|
||
return R.failed(msg=error)
|
||
|
||
# 使用解析后的数据
|
||
name = data.get('name')
|
||
status = data.get('status')
|
||
# ...
|
||
```
|
||
|
||
:::tip 温馨提示
|
||
`parse_request_body()` 返回元组 `(data, error)`,成功时 `data` 为字典、`error` 为 None;失败时 `data` 为 None、`error` 为错误描述字符串。调用方应先检查 `error` 再使用 `data`。
|
||
:::
|
||
|
||
## GET 参数获取
|
||
|
||
Django 中获取 GET 查询参数使用 `request.GET`:
|
||
|
||
```python
|
||
def get_example_page(request):
|
||
# 获取分页参数
|
||
page_no = int(request.GET.get('pageNo', 1))
|
||
page_size = int(request.GET.get('pageSize', PAGE_SIZE))
|
||
|
||
# 获取筛选参数
|
||
name = request.GET.get('name')
|
||
status = request.GET.get('status')
|
||
|
||
if name:
|
||
queryset = queryset.filter(name__contains=name)
|
||
if status:
|
||
queryset = queryset.filter(status=status)
|
||
```
|
||
|
||
## POST 表单参数
|
||
|
||
获取 POST 表单数据使用 `request.POST`:
|
||
|
||
```python
|
||
def upload_file(request):
|
||
# 获取上传的文件
|
||
file = request.FILES.get('file')
|
||
|
||
# 获取表单字段
|
||
field_name = request.POST.get('name', '')
|
||
```
|
||
|
||
## 文件上传参数
|
||
|
||
获取上传文件使用 `request.FILES`:
|
||
|
||
```python
|
||
file = request.FILES.get('file')
|
||
if file:
|
||
original_name = file.name # 原始文件名
|
||
file_size = file.size # 文件大小
|
||
# 分块读取文件内容
|
||
for chunk in file.chunks():
|
||
f.write(chunk)
|
||
```
|
||
|
||
## 表单错误处理
|
||
|
||
`utils/regular.py` 中的 `get_err()` 函数用于提取 Django 表单验证错误信息:
|
||
|
||
```python
|
||
# utils/regular.py
|
||
def get_err(form):
|
||
"""
|
||
获取表单错误文本,多个错误用'/'分隔
|
||
|
||
使用示例:
|
||
form = UserForm(data)
|
||
if not form.is_valid():
|
||
error_msg = get_err(form)
|
||
return R.failed(msg=error_msg)
|
||
"""
|
||
error_list = []
|
||
for item in form.errors.get_json_data().values():
|
||
error_list.append(item[0].get('message'))
|
||
return '/'.join(error_list)
|
||
```
|
||
|
||
## 参数格式化(日志用)
|
||
|
||
`format_params()` 函数将请求参数格式化为 JSON 字符串,自动过滤敏感字段:
|
||
|
||
```python
|
||
# utils/common.py
|
||
def format_params(params):
|
||
"""
|
||
格式化请求参数,自动过滤密码等敏感字段
|
||
敏感字段值替换为 '******'
|
||
"""
|
||
sensitive_fields = ['password', 'old_password', 'new_password', 'confirm_password']
|
||
if isinstance(params, dict):
|
||
params_copy = params.copy()
|
||
for field in sensitive_fields:
|
||
if field in params_copy:
|
||
params_copy[field] = '******'
|
||
return json.dumps(params_copy, ensure_ascii=False)
|
||
return json.dumps(params, ensure_ascii=False)
|
||
```
|
||
|
||
## 日期格式化
|
||
|
||
```python
|
||
# utils/common.py
|
||
def format_datetime(dt, format_str='%Y-%m-%d %H:%M:%S'):
|
||
"""格式化日期时间对象为字符串"""
|
||
return dt.strftime(format_str) if dt else None
|
||
```
|
||
|
||
## 总结
|
||
|
||
请求解析工具函数覆盖了 JSON 请求体解析、GET/POST 参数获取、文件上传、表单验证错误提取等常见场景。`parse_request_body()` 是最核心的函数,返回 `(data, error)` 元组,调用方应先检查错误再使用数据。`get_err()` 将 Django 表单验证错误转换为可读字符串。
|