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)
DRF源码-fields.py的更多相关文章
- DRF源码-views.py
REST框架提供了一个APIView类,它是Django View类的子类. 要了解几个特点: 请求中body中的数据全部都封装到了data中(原POST,PUT,PATCH,DELETE中的数据全部 ...
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- 02 drf源码剖析之快速了解drf
02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- drf源码save以及response
drf源码save以及response 一.save 其中蛮重要的一段 if self.instance is not None: self.instance = self.update(self.i ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- [drf]源码和序列化梳理
drf源码继承管理 # drf继承关系 View APIView as_view: 执行父类的as_view 调用dispatch dispatch init_request request.quer ...
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 07 drf源码剖析之节流
07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...
随机推荐
- SpringBoot之Feign调用方式比较
一:事发原因 两个东家都使用SpringCloud,巴拉巴拉用上了Spring全家桶,从eureka到ribbon,从ribbon到feign,从feign到hystrix,然后在使用feign的时候 ...
- day10-Python运维开发基础(函数嵌套、nonlocal声明局部变量、闭包、locals/globals、lambda表达式)
1. 函数的嵌套与nonlocal 声明局部变量 # ### 函数的嵌套 """ 函数和函数之间可以互相嵌套: 嵌套在内层的叫做内函数 乔涛在外层的叫做外函数 " ...
- node服务端口被占用
今天在输入node .\app.js启动api接口时出现了以下报错: 出现这个报错说明端口被占用:Error: listen EADDRINUSE: address already in use :: ...
- 解题报告:CF622F
懒得码字了: 题目链接:CF622F 很简单的数论题,紫题显然是过了些,(不要说... 对于这个式子,是一个\(k+1\)次的多项式,插\(k+2\)次值就好了,烦人的是处理逆元,我的费马小定理显然是 ...
- pycharm连接mysql数据库的时区问题.
登录到mysql的控制台, 执行: set global time_zone='+8:00'; 这设置的是全局时区,重启后失效. 自MySQL 8.0 GA版本开始支持将参数写入并且持久化: set ...
- go语言的变量和定量
1.变量: 1.var go 的变量非常灵活引入了关键字var. 如 var v1 int var v2 string var v3 [10]int 在go语言中变量申明有更快捷的办法可以把若干个变量 ...
- luogu P4129 [SHOI2006]仙人掌
题目描述 仙人掌图(cactus)是一种无向连通图,它的每条边最多只能出现在一个简单回路(simple cycle)里面.从直观上说,可以把仙人掌图理解为允许存在回路的树.但是仙人掌图和树之间有个本质 ...
- Anaconda下的 Jupyter Notebook 安装 多python环境
装完 Anaconda 会自带一个pyhon环境 也会自带Jupyter Notebook 可以点击开始中的Jupyter Notebook 打开 浏览器 我这里是 3.x 想要装个2.7 的 ...
- 08 SSM整合案例(企业权限管理系统):07.订单操作
04.AdminLTE的基本介绍 05.SSM整合案例的基本介绍 06.产品操作 07.订单操作 08.用户操作 09.权限控制 10.权限关联与控制 11.AOP日志 07.订单操作 SSM订单操作 ...
- linux7下nenux3.14的maven私服搭建和配置使用
为什么用私服,各种帖子很多,话不多说,直接奉上本博主的搭建过程. 一.环境准备:确保jdk和maven安装完成 二.下载nenux:地址:https://www.sonatype.com/downlo ...