django flask 解析数据使用的json解析器

import json
from collections.abc import Iterable


class ParseError(BaseException):
    def __init__(self, message):
        self.message = message

class AttrDict(dict):
    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __getattr__(self, item):
        try:
            return self.__getitem__(item)
        except KeyError:
            raise AttributeError(item)

    def __delattr__(self, item):
        self.__delitem__(item)


# 需要校验的参数对象
class Argument(object):
    """
    Argument object.

    :param name: name of option
    :param default: default value if the argument if absent
    :param bool required: is required
    """

    def __init__(
        self,
        name,
        default=None,
        handler=None,
        required=True,
        type=str,
        filter=None,
        help=None,
        validators=None,
    ):
        self.name = name
        self.default = default
        self.type = type
        self.required = required
        self.filter = filter
        self.help = help
        self.handler = handler
        self.validators = validators
        if not isinstance(self.name, str):
            raise TypeError("Argument name must be string")
        if filter and not callable(self.filter):
            raise TypeError("Argument filter is not callable")

    def parse(self, has_key, value):  # noqa
        if not has_key:
            if self.required and self.default is None:
                raise ParseError(
                    self.help or "Required Error: %s is required" % self.name
                )
            else:
                return self.default
        elif value in ["", None]:
            if self.default is not None:
                return self.default
            elif self.required:
                raise ParseError(
                    self.help or "Value Error: %s must not be null" % self.name
                )
            elif self.help:
                raise ParseError(self.help)
            else:
                return value
        try:
            if self.type:
                if self.type in (list, dict) and isinstance(value, str):
                    value = json.loads(value)
                    assert isinstance(value, self.type)
                elif self.type == bool and isinstance(value, str):
                    assert value.lower() in ["true", "false"]
                    value = value.lower() == "true"
                elif not isinstance(value, self.type):
                    value = self.type(value)
        except (TypeError, ValueError, AssertionError):
            raise ParseError(
                self.help or "Type Error: %s type must be %s" % (self.name, self.type)
            )

        if self.filter:
            if not self.filter(value):
                raise ParseError(
                    self.help or "Value Error: %s filter check failed" % self.name
                )

        if isinstance(self.validators, Iterable):
            for validator in self.validators:
                validator(value)

        if self.handler:
            value = self.handler(value)
        return value


# 解析器基类
class BaseParser(object):
    def __init__(self, *args):
        self.args = []
        for e in args:
            if isinstance(e, str):
                e = Argument(e)
            elif not isinstance(e, Argument):
                raise TypeError("%r is not instance of Argument" % e)
            self.args.append(e)

    def _get(self, key):
        raise NotImplementedError

    def _init(self, data):
        raise NotImplementedError

    def add_argument(self, **kwargs):
        self.args.append(Argument(**kwargs))

    def parse(self, data=None, clear=False):
        rst = AttrDict()
        try:
            self._init(data)
            for e in self.args:
                has_key, value = self._get(e.name)
                if clear and has_key is False and e.required is False:
                    continue
                rst[e.name] = e.parse(has_key, value)
        except ParseError as err:
            return None, err.message
        return rst, None


# Json解析器
class JsonParser(BaseParser):
    def __init__(self, *args):
        self.__data = None
        super(JsonParser, self).__init__(*args)

    def _get(self, key):
        return key in self.__data, self.__data.get(key)

    def _init(self, data):
        try:
            if isinstance(data, (str, bytes)):
                self.__data = json.loads(data) if data else {}
            else:
                assert hasattr(data, "__contains__")
                assert hasattr(data, "get")
                assert callable(data.get)
                self.__data = data
        except (ValueError, AssertionError):
            raise ParseError("Invalid data type for parse")

 使用方法:

post 方法:

        form, error = JsonParser(
            Argument(
                "username",
                required=True,
                type=str,
            ),
            Argument(
                "password",
                required=True,
                type=str,
            ),
            Argument(
                "permission",
                required=False,
                type=str,
            ),
            Argument(
                "email",
                required=False,
                type=str,
            ),
            Argument(
                "phone",
                required=False,
                type=str,
            )
        ).parse(request.body)
        
        if error:
            return FailResponse(code=CODE.LOGINERROR.code, message=error)

get 使用方法

        form, error = JsonParser(
            Argument(
                "username",
                required=True,
                type=str,
            ),
            Argument(
                "permission_name",
                required=True,
                type=str,
            ),
            Argument(
                "permission_value",
                required=True,
                type=bool,
            ),
        ).parse(request.GET)
        
        if error:
            return FailResponse(code=CODE.LOGINERROR.code, error=error)

 

posted @ 2024-07-19 18:23  小天狼鑫  阅读(11)  评论(0编辑  收藏  举报