真香-- 基于schema的复杂请求参数,请求体,字典校验方法

您还在怎么校验请求体,请求参数,复杂嵌套字典?使用if…else…,for…?,oh No,小心leader给你加“鸡腿”,今天给大家分享一种博主使用很久的参数校验方式。具有无限嵌套一次校验,配置简单可读性高,兼容函数等诸多优点

场景:校验以下格式的示例参数

my_data = {
    "header_data": {
        "user_name": {
            "first_name": "请关注下面这个公众号",    # 必填 全中文,少于20字
            "second_name": "Hello Python",    # 选填,或只能填写字符串 少于20字
            "msg": ["都是干货", 5, 6, 7]        # 必填,列表可为空,或只能填写字符串或整数
        },
        "age_binning": {
            "hospitalizations": ["aa", "bb", "cc", "dd"],
            "population": [5, 6, 7, 8]
        }
    },
    "day_data": {  
        "2020-03-16": {                     # 可变key,必填,校验其格式
            "weather": "rain",              # 选填
            "temperature": {
                "average": 1.638889,
                "min": -2.604167,
                "max": 78,
            }
        },
        "2020-03-17": { 
            "weather": "snow", 
            "temperature": {
                "average": 1.638889,
                "min": -2.604167,
                "max": 8,
            }
        },
    }
}

使用schema 校验如下:具体语法可参考schema官方说明。

from schema import Regex, Or, Schema, And, Optional

def is_all_zh_digit(s):
    """
    校验全是汉字
    """
    if not s:
        return False
    for c in s:
        if not (('\u4e00' <= c <= '\u9fa5') or c.isdigit()):
            return False
    return True


sample = Schema({
    "header_data": {
        "user_name": {
            "first_name": And(str, lambda n: len(n) < 20 and is_all_zh_digit(n),
                              error='first_name is needed or Invalid'),
            Optional('second_name'): And(str, lambda n: len(n) < 20, error='second_name Invalid'),
            "msg": [Or(str, int, None, lambda n: len(n) <= 100, error='msg Invalid')]
        },
        "age_binning": {
            "hospitalizations": [str],
            "population": [int]
        }
    },
    "day_data": {
        Regex('^[0-9]{4}-[0-9]{2}-[0-9]{2}'): {
            Optional('weather'): str,
            "temperature": {
                "average": float,
                "min": float,
                "max": int,
            }
        },
    }
})

try:
    sample.validate(my_data)
    print('true')
except Exception as e:
    print(e)

当在接口中校验请求json数据时,Django类视图示例:
在这里插入图片描述
在基类LoonBaseView中进行校验:

import simplejson
import json
from django.views import View

from services.pub_demos.demo_common import api_response


class LoonBaseView(View):
    """
    base view for params validate
    """
    def dispatch(self, request, *args, **kwargs):

        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        request_method = request.method.lower()
        meth_schema = getattr(self, request.method.lower() + '_schema', None)
        if meth_schema and request_method in ['post', 'patch', 'put']:
            try:
                json_dict = simplejson.loads(request.body)
                print(json_dict)
                meth_schema.validate(json_dict)
            except Exception as e:
                print(e.__str__())
                return api_response(-1, '请求参数不合法:{}'.format(e.__str__()), {})

        return handler(request, *args, **kwargs)

是不是很方便,赶快体验吧,更多干货,请关注公众号:Hello Python

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值