From 4e565ed4d8d767922f114d6a3bd8360f86e1b344 Mon Sep 17 00:00:00 2001 From: chenzuoqing Date: Wed, 8 Dec 2021 16:51:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84model=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=81=E4=BF=AE=E6=94=B9=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=87=8D=E5=A4=8D=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/views.py | 55 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/src/common/views.py b/src/common/views.py index 90d77d9..6c7300d 100644 --- a/src/common/views.py +++ b/src/common/views.py @@ -1,9 +1,38 @@ +from typing import List, Dict + from flask import request from flask_restful import abort, Resource, marshal, fields, reqparse 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): """Mongodb 模型视图相关方法的扩展集合""" # 模型 @@ -73,18 +102,20 @@ class ModelViewBase(Resource): return errors = [] - for field in self.uniq_fields: - val = args.get(field) - if val: - exists = self.model.objects(**{field: val}).first() - # 若存在,以下两种情况需要判断: - # 1. 创建时检查内容是否能匹配对象,匹配到返回异常 - # 2. 更新时若存在重复,并且不是当前修改的对象,返回异常 - if exists and ((not obj) or (obj and obj.id != exists.id)): - errors.append(f"提交的 {field} 已存在") + uniq_query = parse_uniq_fields(args, self.uniq_fields) + for field in uniq_query: + exists = self.model.objects(**field).first() + # 若存在,以下两种情况需要判断: + # 1. 创建时检查内容是否能匹配对象,匹配到返回异常 + # 2. 更新时若存在重复,并且不是当前修改的对象,返回异常 + if exists and ((not obj) or (obj and obj.id != exists.id)): + errors.append(f"提交的 {list(field.keys())} 已存在") if errors: abort_response(400, 1001, msg=f"部分字段需要唯一,请检查重复!", errors=errors) + def validate_fields(self, args: dict, create=True) -> dict: + return args + class ListMixin(ModelViewBase): @@ -115,9 +146,10 @@ class CreateMixin(ModelViewBase): # 解析参数 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) @@ -172,7 +204,8 @@ class UpdateMixin(ModelViewBase): # 解析参数 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不同认为异常 self.validate_uniq_fields(args, obj=obj)