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)

  

DRF源码-fields.py的更多相关文章

  1. DRF源码-views.py

    REST框架提供了一个APIView类,它是Django View类的子类. 要了解几个特点: 请求中body中的数据全部都封装到了data中(原POST,PUT,PATCH,DELETE中的数据全部 ...

  2. Django之DRF源码分析(二)---数据校验部分

    Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...

  3. 02 drf源码剖析之快速了解drf

    02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...

  4. Django与drf 源码视图解析

    0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...

  5. drf源码save以及response

    drf源码save以及response 一.save 其中蛮重要的一段 if self.instance is not None: self.instance = self.update(self.i ...

  6. DRF源码系列分析

    DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流

  7. [drf]源码和序列化梳理

    drf源码继承管理 # drf继承关系 View APIView as_view: 执行父类的as_view 调用dispatch dispatch init_request request.quer ...

  8. drf源码剖析系列(系列目录)

    drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...

  9. 07 drf源码剖析之节流

    07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...

随机推荐

  1. SpringBoot之Feign调用方式比较

    一:事发原因 两个东家都使用SpringCloud,巴拉巴拉用上了Spring全家桶,从eureka到ribbon,从ribbon到feign,从feign到hystrix,然后在使用feign的时候 ...

  2. day10-Python运维开发基础(函数嵌套、nonlocal声明局部变量、闭包、locals/globals、lambda表达式)

    1. 函数的嵌套与nonlocal 声明局部变量 # ### 函数的嵌套 """ 函数和函数之间可以互相嵌套: 嵌套在内层的叫做内函数 乔涛在外层的叫做外函数 " ...

  3. node服务端口被占用

    今天在输入node .\app.js启动api接口时出现了以下报错: 出现这个报错说明端口被占用:Error: listen EADDRINUSE: address already in use :: ...

  4. 解题报告:CF622F

    懒得码字了: 题目链接:CF622F 很简单的数论题,紫题显然是过了些,(不要说... 对于这个式子,是一个\(k+1\)次的多项式,插\(k+2\)次值就好了,烦人的是处理逆元,我的费马小定理显然是 ...

  5. pycharm连接mysql数据库的时区问题.

    登录到mysql的控制台, 执行: set global time_zone='+8:00'; 这设置的是全局时区,重启后失效. 自MySQL 8.0 GA版本开始支持将参数写入并且持久化: set ...

  6. go语言的变量和定量

    1.变量: 1.var go 的变量非常灵活引入了关键字var. 如 var v1 int var v2 string var v3 [10]int 在go语言中变量申明有更快捷的办法可以把若干个变量 ...

  7. luogu P4129 [SHOI2006]仙人掌

    题目描述 仙人掌图(cactus)是一种无向连通图,它的每条边最多只能出现在一个简单回路(simple cycle)里面.从直观上说,可以把仙人掌图理解为允许存在回路的树.但是仙人掌图和树之间有个本质 ...

  8. Anaconda下的 Jupyter Notebook 安装 多python环境

    装完 Anaconda 会自带一个pyhon环境   也会自带Jupyter Notebook   可以点击开始中的Jupyter Notebook 打开 浏览器 我这里是 3.x 想要装个2.7 的 ...

  9. 08 SSM整合案例(企业权限管理系统):07.订单操作

    04.AdminLTE的基本介绍 05.SSM整合案例的基本介绍 06.产品操作 07.订单操作 08.用户操作 09.权限控制 10.权限关联与控制 11.AOP日志 07.订单操作 SSM订单操作 ...

  10. linux7下nenux3.14的maven私服搭建和配置使用

    为什么用私服,各种帖子很多,话不多说,直接奉上本博主的搭建过程. 一.环境准备:确保jdk和maven安装完成 二.下载nenux:地址:https://www.sonatype.com/downlo ...