• DRF源码-fields.py


    https://www.cnblogs.com/pyspark/p/8607801.html

    https://www.cnblogs.com/LYliangying/articles/9896548.html

    fieids.py主要定义了各种字段的序列化类。Field是基类。

    class Field

        _creation_counter = 0
    
        default_error_messages = {
            'required': _('This field is required.'),
            'null': _('This field may not be null.')
        }
        default_validators = []     #默认验证器初始化为空list
        default_empty_html = empty
        initial = None
    

      

        # 在构造函数中,给出了各种定义参数,由子类继承,在实例化时传参,来控制这个字段的各种属性
        # read_only,表明只用于序列化输出
        # write_only, 表明只用于反序列化输入,比如密码
        # required, 表明在反序列化时必须输入
        # default, 反序列化时使用的默认值
        # initial
        # source,
        # label, 用于HTML展示API页面时,显示的字段名称
        # help_text, 用于HTML展示API页面时,显示的字段帮助提示信息
        # style
        # error_messages, 包含错误编号与错误信息的字典
        # validators, 该字段使用的验证器
        # allow_null, 表明该字段是否允许传入None,默认False
        def __init__(self, read_only=False, write_only=False,
                     required=None, default=empty, initial=empty, source=None,
                     label=None, help_text=None, style=None,
                     error_messages=None, validators=None, allow_null=False):
            self._creation_counter = Field._creation_counter
            Field._creation_counter += 1
    
            # If `required` is unset, then use `True` unless a default is provided.
            if required is None:
                required = default is empty and not read_only
    
            # Some combinations of keyword arguments do not make sense.
            # 断言一些没有意义的参数组合
            assert not (read_only and write_only), NOT_READ_ONLY_WRITE_ONLY
            assert not (read_only and required), NOT_READ_ONLY_REQUIRED
            assert not (required and default is not empty), NOT_REQUIRED_DEFAULT
            assert not (read_only and self.__class__ == Field), USE_READONLYFIELD
    
            # 将传入的参数赋值给实例(属性初始化)
            self.read_only = read_only
            self.write_only = write_only
            self.required = required
            self.default = default
            self.source = source
            self.initial = self.initial if (initial is empty) else initial
            self.label = label
            self.help_text = help_text
            self.style = {} if style is None else style
            self.allow_null = allow_null
    
            if self.default_empty_html is not empty:
                if default is not empty:
                    self.default_empty_html = default
    
            if validators is not None:
                self.validators = list(validators)
    
            # These are set up by `.bind()` when the field is added to a serializer.
            self.field_name = None
            self.parent = None
    
            # Collect default error message from self and parent classes
            messages = {}
            for cls in reversed(self.__class__.__mro__):
                messages.update(getattr(cls, 'default_error_messages', {}))
            messages.update(error_messages or {})
            self.error_messages = messages
    

      

        # .validators is a lazily loaded property, that gets its default
        # value from `get_validators`.
        # validators属性设置
        @property
        def validators(self):
            if not hasattr(self, '_validators'):
                self._validators = self.get_validators()
            return self._validators
    
        @validators.setter
        def validators(self, validators):
            self._validators = validators
    
        def get_validators(self):
            return list(self.default_validators)
    

      

    子类

    class IntegerField(Field):
        default_error_messages = {
            'invalid': _('A valid integer is required.'),
            'max_value': _('Ensure this value is less than or equal to {max_value}.'),
            'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
            'max_string_length': _('String value too large.')
        }
        MAX_STRING_LENGTH = 1000  # Guard against malicious string inputs.
        re_decimal = re.compile(r'.0*s*$')  # allow e.g. '1.0' as an int, but not '1.2'
    
        def __init__(self, **kwargs):
            # 从变长传参里找max_value,min_value,给到实例,默认为None
            #继承父类的其他属性(相当于父类属性是通用,这里的属性是子类独有的)
            self.max_value = kwargs.pop('max_value', None)
            self.min_value = kwargs.pop('min_value', None)
            super().__init__(**kwargs)
            # 如果传参max_value,先拼接error message,然后在validators属性里添加一个验证器元素。
            if self.max_value is not None:
                message = lazy_format(self.error_messages['max_value'], max_value=self.max_value)
                self.validators.append(
                    MaxValueValidator(self.max_value, message=message))
            if self.min_value is not None:
                message = lazy_format(self.error_messages['min_value'], min_value=self.min_value)
                self.validators.append(
                    MinValueValidator(self.min_value, message=message))
    
        def to_internal_value(self, data):
            if isinstance(data, str) and len(data) > self.MAX_STRING_LENGTH:
                self.fail('max_string_length')
    
            try:
                data = int(self.re_decimal.sub('', str(data)))
            except (ValueError, TypeError):
                self.fail('invalid')
            return data
    
        def to_representation(self, value):
            return int(value)
    

      

    class CharField(Field):
        default_error_messages = {
            'invalid': _('Not a valid string.'),
            'blank': _('This field may not be blank.'),
            'max_length': _('Ensure this field has no more than {max_length} characters.'),
            'min_length': _('Ensure this field has at least {min_length} characters.'),
        }
        initial = ''
    
        def __init__(self, **kwargs):
            self.allow_blank = kwargs.pop('allow_blank', False)
            self.trim_whitespace = kwargs.pop('trim_whitespace', True)
            self.max_length = kwargs.pop('max_length', None)
            self.min_length = kwargs.pop('min_length', None)
            super().__init__(**kwargs)
            if self.max_length is not None:
                message = lazy_format(self.error_messages['max_length'], max_length=self.max_length)
                self.validators.append(
                    MaxLengthValidator(self.max_length, message=message))
            if self.min_length is not None:
                message = lazy_format(self.error_messages['min_length'], min_length=self.min_length)
                self.validators.append(
                    MinLengthValidator(self.min_length, message=message))
    
            # ProhibitNullCharactersValidator is None on Django < 2.0
            if ProhibitNullCharactersValidator is not None:
                self.validators.append(ProhibitNullCharactersValidator())
    
        def run_validation(self, data=empty):
            # Test for the empty string here so that it does not get validated,
            # and so that subclasses do not need to handle it explicitly
            # inside the `to_internal_value()` method.
            if data == '' or (self.trim_whitespace and str(data).strip() == ''):
                if not self.allow_blank:
                    self.fail('blank')
                return ''
            return super().run_validation(data)
    
        # 将int,float转为为str
        def to_internal_value(self, data):
            # We're lenient with allowing basic numerics to be coerced into strings,
            # but other types should fail. Eg. unclear if booleans should represent as `true` or `True`,
            # and composites such as lists are likely user error.
            if isinstance(data, bool) or not isinstance(data, (str, int, float,)):
                self.fail('invalid')
            value = str(data)
            return value.strip() if self.trim_whitespace else value
    
        def to_representation(self, value):
            return str(value)
    

      

  • 相关阅读:
    Sublime Text 3 配置 PHPCS 插件
    Rainmeter 一部分 语法 中文教程
    极域电子教室卸载或安装软件后windows7无法启用触摸板、键盘
    一些常用&实用的Linux命令
    理解linux sed命令
    vi入门到精通
    Vim的行号、语法显示等设置(.vimrc文件的配置)以及乱码解决
    SliTaz 从入门到精通
    Slitaz定制
    Slitaz 中文定制手册
  • 原文地址:https://www.cnblogs.com/jabbok/p/11294379.html
Copyright © 2020-2023  润新知