(三)想使用flaskrestful 测试用例管理平台 优化了参数校验、和其他

优化了参数校验

MyRequestParseUtil
添加了参数 isExist 、 参数都是模型类、通过name 获取带校验id 不存在raise
添加了参数 unique 参数都是模型类、通过name 获得field 去查询是否重名

这俩参数 只针对 post 请求创建新的数据、对于put 修改时候没有去兼容、要不就是重复校验、要不就是会出现意想不到的错误

 			#  校验cls ID
            if kw.get("isExist"):
                cls = kw.get("isExist")
                cls.get(self.body.get(kw['name']), kw['name'])
            #   校验cls 重名
            if kw.get("unique"):
                cls = kw.get("unique")
                cls.verify_unique(**{kw['name']: self.body.get(kw['name'])})

#--------------------------------------------------------------------------------
class Base(db.Model):
		@classmethod
    	def get(cls, ident: int, name: AnyStr = None):
        """
        get entity by id
        :param ident: field id
        :param name: field name
        :return: get_or_NoFound
        """
        	return cls.query.get_or_NoFound(ident, name)
         @classmethod
    	def verify_unique(cls, **kwargs) -> None:
	        """verify_unique by field name"""
	        rv = cls.query.filter_by(**kwargs).first()
	        if rv:
	            raise ParamException(ResponseMsg.already_exist(list(kwargs.values())[0]))
#--------------------------------------------------------------------------------
class MyBaseQuery(BaseQuery):

 		def get_or_NoFound(self, ident, name) -> Any:
        """
        get self by id
        :param ident: id
        :param name:  cls.__name__
        :return: cls.self
        :raise:ParamException
        """

	        rv = self.get(ident)
	        if not rv:
	            raise ParamException(ResponseMsg.no_existent(name))
	        return rv

参数校验完整代码

也有优化了一些对于 是否必传等逻辑问题、

class MyRequestParseUtil:

    def __init__(self, location: AnyStr = "json"):
        """
        :param location:  "json" -> application/json | "values"  -> query default json
        """

        self.location = location
        self.args = []
        try:
            self.body = getattr(request, self.location, {})
        except Exception as e:
            log.error(e)
            raise ParamException(ResponseMsg.REQUEST_BODY_ERROR)

    def add(self, **kwargs):
        """
        添加请求数据与数据类型
        :param kwargs: name
        :param kwargs: type
        :param kwargs: required bool
        :param kwargs: default
        :param kwargs: choices
        :param kwargs: isExist=cls  put 请求主键还会再校验一次 不需要添加 添加外键
        :param kwargs: unique  put 不要添加


        """
        # 默认类型为字符
        if not kwargs.get("type"):
            kwargs.setdefault("type", str)
        # 默认非必传
        if not kwargs.get("required"):
            kwargs.setdefault("required", False)
        self.args.append(kwargs)

    def parse_args(self) -> Dict:
        """
        参数校验
        :return: self.body
        """

        self.body = dict(self.body)
        for kw in self.args:
            # 分页数据
            if kw["name"] == "page":
                self.body[kw["name"]] = self.__verify_page(self.body.get(kw['name'], kw.get("default")))
            if kw['name'] == "limit":
                self.body[kw["name"]] = self.__verify_limit(self.body.get(kw["name"], kw.get("default")))

            #  必传
            if kw['required'] is True:
                self.__verify_empty(self.body.get(kw["name"]), kw["name"])
            # 非必传
            else:
                # 未传
                if self.body.get(kw["name"]) is None:
                    if kw.get('default'):
                        self.body[kw['name']] = kw.get('default')
                    else:
                        continue
            self.__verify_type(self.body.get(kw["name"]), kw['type'])

            if kw.get("choices"):
                self.__verify_choices(self.body.get(kw["name"]), kw['choices'])
            #  校验cls ID
            if kw.get("isExist"):
                cls = kw.get("isExist")
                cls.get(self.body.get(kw['name']), kw['name'])
            #   校验cls 重名
            if kw.get("unique"):
                cls = kw.get("unique")
                cls.verify_unique(**{kw['name']: self.body.get(kw['name'])})

        return self.body

    def __verify_page(self, page: AnyStr) -> int:
        """
        page校验
        :param page: 页
        :raise: ParamException
        :return page
        """
        if int(page) < 1:
            raise ParamException(ResponseMsg.error_param("page", "must > 0"))
        return page

    def __verify_limit(self, limit: AnyStr) -> int:
        """
        limit 校验
        :param limit: 行
        :return: limit
        """
        if int(limit) < 0:
            raise ParamException(ResponseMsg.error_param("limit", "must > 0"))
        return limit

    def __verify_empty(self, target: AnyStr, filed: AnyStr):
        """
        校验参数是否为空
        :param target:  目标值
        :param filed:   参数名
        :raise: ParamException
        """
        if target is None or target == "":
            raise ParamException(ResponseMsg.empty(filed))

    def __verify_type(self, target: Any, t: type, ):
        """
        校验类型
        :param target: 目标值
        :param t: 期望类型
        :raise: ParamException
        """
        if not isinstance(target, t):
            raise ParamException(ResponseMsg.error_type(target, t))

    def __verify_choices(self, target: Any, choices: List):
        """
        区间校验
        :param target: 目标值
        :param choices:
        :raise: ParamException
        """

        if target not in choices:
            raise ParamException(ResponseMsg.error_val(target, choices))


使用
class CaseController(Resource):

    @auth.login_required
    def post(self) -> MyResponse:
        parse = MyRequestParseUtil()
        parse.add(name="title", type=str, required=True, unique=Cases)
        parse.add(name="versionID", type=int, isExist=Version, required=True)
        parse.add(name="steps", type=dict, required=True)
        ...
        case = parse.parse_args()
        Cases(**case).save()
        return MyResponse.success()

关于修改

封装了个update
通过cls.__table__.columns 修改其属性
但还是要通过get 获取实体对象
修改的时候把id 主键pop出去

class Base(db.Model):
	def save(self):
        """save"""
        try:
            db.session.add(self)
            db.session.commit()
        except Exception as e:
            log.error(e)
            db.session.rollback()
            raise MyException()
	
	@classmethod
    def update(cls, **kwargs):
        """
        通过kwargs.get('id') 获得实例 修改
        """
        
        target = cls.get(kwargs.pop('id'))
        c = [i.name for i in cls.__table__.columns]
        for k, v in dict(kwargs).items():
            if k in c:
                setattr(target, k, v)
        target.save()

使用update

项目实体修改 需要ADMIN or ProjectADMIN
需要做个权限校验
通过flaskg 获得user
使用super 调用父类update
整个更新过程中通过get 查询了两次库、暂时没想到怎么优化

class Project(Base):
	
 	@classmethod
    def update(cls, **kwargs):
        """
        添加权限过滤
        必须是ADMIN or AdminID
        :param kwargs: Project
        """
        from flask import g
        target = cls.get(kwargs.get('id'), f"{cls.__name__} id")
        if not g.user.admin or not g.user.id != target.adminID:
            raise AuthException()
        return super(Project, Project).update(**kwargs)

class ProjectController(Resource):
	@auth.login_required
    def put(self) -> MyResponse:
        """
        维护
        :return: MyResponse
        """
        from Models.UserModel.users import User
        parse = MyRequestParseUtil()
        parse.add(name="id", type=int, required=True)
        parse.add(name="name", type=str, required=False)
        parse.add(name="desc", type=str, required=False)
        parse.add(name="adminID", type=int, isExist=User, required=False)
        Project.update(**parse.parse_args())
        return MyResponse.success()

写道最后

目前进度就是这样、有的模块没有录入 flask 也是边写边学、有好的想法的大佬可以留言。thank u
附上github github

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值