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)

  

原文地址:https://www.cnblogs.com/jabbok/p/11294379.html

时间: 2024-08-05 14:56:49

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

死磕itchat源码--core.py

core.py文件中的Core类定义了itchat的所有接口.且,仅仅是定义了接口,全部在component包中实现重构.其用法如下表述: 缺省 源码如下: # -*- encoding: utf-8 -*- import logging import requests from . import config, storage, utils, log from .components import load_components class Core(object): """

死磕itchat源码--config.py

itchat的配置文件,源码: import os, platform # 版本及微信的url,二维码等 VERSION = '1.3.10' BASE_URL = 'https://login.weixin.qq.com' OS = platform.system() # Windows, Linux, Darwin DIR = os.getcwd() DEFAULT_QR = 'QR.png' TIMEOUT = (10, 60) # 代理配置 USER_AGENT = 'Mozilla/5

基于单层决策树的AdaBoost算法源码

基于单层决策树的AdaBoost算法源码 Mian.py 1 # -*- coding: utf-8 -*- 2 # coding: UTF-8 3 4 import numpy as np 5 from AdaBoost import AdaBoost 6 from sklearn.model_selection import train_test_split 7 from sklearn.metrics import accuracy_score 8 9 def main(): 10 11

Python Django 生命周期 中间键 csrf跨站请求伪造 auth认证模块 settings功能插拔式源码

一 django 生命周期 二 django中间键 1.什么是中间键 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功能. 简单来说就相当于django门户,保安:它本质上就是一个自定义类,类中定义了几个方法. 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models): 响应走的时候也需要经过中间件才能到达w

Drf03 /呼啦圈网页初步实现、drf筛选、视图(源码实现)

目录 Drf03 /呼啦圈网页初步实现.drf筛选.视图(源码实现) 内容回顾与补充 今日详细 1.呼啦圈初步实现 2. 筛选 3.视图 Drf03 /呼啦圈网页初步实现.drf筛选.视图(源码实现) 内容回顾与补充 restful规范 - URL中一般用名词: http://www.luffycity.com/article/ (面向资源编程,网络上东西都视为资源) - 根据请求不同做不同操作:GET/POST/PUT/DELTE/PATCH - 筛选条件,在URL参数中进行传递: http:

DRF之APIView源码解析

目录 Django项目中的代码如下 APIView源码解析 源码解析总结 Django项目中的代码如下 urls.py中: from django.conf.urls import url from app import views urlpatterns = [ url(r'^test/$', views.APIViewSourceCode.as_view()), ] views.py中: from rest_framework.views import APIView class APIVi

REST、DRF(View源码解读、APIView源码解读)

一.REST 1.什么是编程? 数据结构和算法的结合 2.什么是REST? 首先我们回顾下我们之前的图书管理系统,我们设计了这样的URL,如下: 127.0.0.1:9001/books/ 127.0.0.1:9001/get_all_books/ 访问所有的数据 127.0.0.1:9001/books/{id}/ 127.0.0.1:9001/books/{id}?method=get 访问单条数据 127.0.0.1:9001/books/add/ 127.0.0.1:9001/books

DRF部分源码简介及序列化组件

一:解析模块 (1)作用: (1)drf给我们通过了多种解析数据包方式的解析类 (2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些数据不解析 (3)全局配置就是针对每一个视图类,局部配置就是针对指定的视图来,让它们可以按照配置规则选择性解析数据 (2)源码入口 # APIView类的dispatch方法中 request = self.initialize_request(request, *args, **kwargs) # 点进去 # 获取解析类 parsers=self.

DRF ---- APIview生命周期 请求/渲染/解析/异常/响应/ 模块源码 drf配置

目录 drf框架的封装风格 1. 原生Django View的源码复习 as_view源码 dispatch源码 2. ApiView的生命周期(源码) 重写的as_view源码 重写的dispatch源码 3 . 请求模块 initialize_request 源码 Request 源码 Request 下 __getattr_ 源码 总结(重点) 4. 渲染模块(了解) 5. Drf配置(重点) drf APISettings 默认配置 drf框架 自定义 全局配置 drf框架 自定义 局部