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. 【剑指Offer面试编程题】题目1370:数组中出现次数超过一半的数字--九度OJ

    题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...

  2. Core Data 基本数据操作 增删改查 排序

    所有操作都基于Core Data框架相关 API,工程需要添加CoreData.framework支持 1.增  NSEntityDescription insertNewObjectForEntit ...

  3. 洛谷P4427 [BJOI2018]求和

    \(\Large\textbf{Description: } \large{一颗n个节点的树,m次询问,每次查询点i到点j的路径上所有节点点深度的k次方的和并对998244353取模(1\leq n, ...

  4. SQL*Loader-128: SQL*Loader-523

    错误原因: SQL*Loader-128: unable to begin a sessionORA-01017: invalid username/password; logon denied 解决 ...

  5. Ubuntu安装Orcale

    Linux_Ubuntu安装oracle总结 ---------转自 https://www.2cto.com/database/201305/215338.html 话说我花了一晚上才在ubuntu ...

  6. 【转】Windows中使用TortoiseGit提交项目到GitLab配置

    转  原文地址 https://www.cnblogs.com/xiangwengao/p/4134492.html   下文来给各位介绍Windows中使用TortoiseGit提交项目到GitLa ...

  7. 主机ping虚拟机失败。虚拟机ping主机,可以ping通。

    原文:https://blog.csdn.net/ww1473345713/article/details/51490525 今天打开虚拟机,然后用Xshell远程连接,发现连接不上.按照以下顺序检查 ...

  8. java中数组输出的方式

    方式1:遍历输出 public class Main { public static void main(String[] args) { int[] ns = { 1, 4, 9, 16, 25 } ...

  9. Java程序员学习Go指南(三)

    转载:https://www.luozhiyun.com/archives/213 人是否会进步以及进步得有多快,依赖的恰恰就是对自我的否定,这包括否定的深刻与否,以及否定自我的频率如何.这其实就是& ...

  10. 031.SAP上查看所有的用户账号,查询SAP用户账号的后台数据库表

    01. 输入事务代码SU11, 然后输入SAP用户账号数据表USER_ADDR 02. 点击实用程序,再点击内容 03.点击查询 04. 将查看到的结果通过Excel表格导出 不忘初心,如果您认为这篇 ...