完善model对象新增、修改的数据重复检查
This commit is contained in:
parent
43d3aa20ff
commit
4e565ed4d8
|
@ -1,9 +1,38 @@
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask_restful import abort, Resource, marshal, fields, reqparse
|
from flask_restful import abort, Resource, marshal, fields, reqparse
|
||||||
|
|
||||||
from common.utils import abort_response
|
from common.utils import abort_response
|
||||||
|
|
||||||
|
|
||||||
|
def parse_uniq_fields(args, many_field) -> List[Dict]:
|
||||||
|
""" 注意,请再请求解析中判断必须的字段!!!
|
||||||
|
得到唯一组合的查询,如
|
||||||
|
many_field = [
|
||||||
|
"name", # `args` 中的检查 `name` 值是否存在
|
||||||
|
["num", "channel_id"], # 组合是否存在
|
||||||
|
{"host_id": "", port: 111}, # 组合,带默认值,若 `args` 未包含参数将用默认值得到查询
|
||||||
|
]
|
||||||
|
:param args: dict 请求传入的参数
|
||||||
|
:param many_field: 必须是个可迭代对象,可以包含几种情况
|
||||||
|
"""
|
||||||
|
query = []
|
||||||
|
for field in many_field:
|
||||||
|
if isinstance(field, str):
|
||||||
|
value = args.get(field)
|
||||||
|
if value:
|
||||||
|
query.append({field: value})
|
||||||
|
if isinstance(field, dict):
|
||||||
|
query.append(
|
||||||
|
{key: (args.get(key) or default) for key, default in field.items()}
|
||||||
|
)
|
||||||
|
if isinstance(field, tuple) or isinstance(field, list):
|
||||||
|
# query.append({key: args.get(key) for key in field if args.get(key)})
|
||||||
|
query.append({key: args.get(key) for key in field})
|
||||||
|
return query
|
||||||
|
|
||||||
|
|
||||||
class ModelViewBase(Resource):
|
class ModelViewBase(Resource):
|
||||||
"""Mongodb 模型视图相关方法的扩展集合"""
|
"""Mongodb 模型视图相关方法的扩展集合"""
|
||||||
# 模型
|
# 模型
|
||||||
|
@ -73,18 +102,20 @@ class ModelViewBase(Resource):
|
||||||
return
|
return
|
||||||
|
|
||||||
errors = []
|
errors = []
|
||||||
for field in self.uniq_fields:
|
uniq_query = parse_uniq_fields(args, self.uniq_fields)
|
||||||
val = args.get(field)
|
for field in uniq_query:
|
||||||
if val:
|
exists = self.model.objects(**field).first()
|
||||||
exists = self.model.objects(**{field: val}).first()
|
|
||||||
# 若存在,以下两种情况需要判断:
|
# 若存在,以下两种情况需要判断:
|
||||||
# 1. 创建时检查内容是否能匹配对象,匹配到返回异常
|
# 1. 创建时检查内容是否能匹配对象,匹配到返回异常
|
||||||
# 2. 更新时若存在重复,并且不是当前修改的对象,返回异常
|
# 2. 更新时若存在重复,并且不是当前修改的对象,返回异常
|
||||||
if exists and ((not obj) or (obj and obj.id != exists.id)):
|
if exists and ((not obj) or (obj and obj.id != exists.id)):
|
||||||
errors.append(f"提交的 {field} 已存在")
|
errors.append(f"提交的 {list(field.keys())} 已存在")
|
||||||
if errors:
|
if errors:
|
||||||
abort_response(400, 1001, msg=f"部分字段需要唯一,请检查重复!", errors=errors)
|
abort_response(400, 1001, msg=f"部分字段需要唯一,请检查重复!", errors=errors)
|
||||||
|
|
||||||
|
def validate_fields(self, args: dict, create=True) -> dict:
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
class ListMixin(ModelViewBase):
|
class ListMixin(ModelViewBase):
|
||||||
|
|
||||||
|
@ -115,9 +146,10 @@ class CreateMixin(ModelViewBase):
|
||||||
|
|
||||||
# 解析参数
|
# 解析参数
|
||||||
args = self.request_parse.parse_args()
|
args = self.request_parse.parse_args()
|
||||||
|
validated_data = self.validate_fields(args, create=True)
|
||||||
|
|
||||||
# 创建前钩子,
|
# 创建前钩子,
|
||||||
validated_data = self.pre_create(args)
|
validated_data = self.pre_create(validated_data)
|
||||||
|
|
||||||
# 检查重复:检查提交的唯一字段值,是否有存在的对象
|
# 检查重复:检查提交的唯一字段值,是否有存在的对象
|
||||||
self.validate_uniq_fields(args)
|
self.validate_uniq_fields(args)
|
||||||
|
@ -172,7 +204,8 @@ class UpdateMixin(ModelViewBase):
|
||||||
|
|
||||||
# 解析参数
|
# 解析参数
|
||||||
args = self.request_parse.parse_args()
|
args = self.request_parse.parse_args()
|
||||||
validated_data = self.pre_update(obj, args)
|
validated_data = self.validate_fields(args, create=False)
|
||||||
|
validated_data = self.pre_update(obj, validated_data)
|
||||||
|
|
||||||
# 检查重复:检查提交的唯一字段值,是否有存在的对象,与当前对象id不同认为异常
|
# 检查重复:检查提交的唯一字段值,是否有存在的对象,与当前对象id不同认为异常
|
||||||
self.validate_uniq_fields(args, obj=obj)
|
self.validate_uniq_fields(args, obj=obj)
|
||||||
|
|
Loading…
Reference in New Issue