wtforms源码流程
未实例化前
1.继承的Form类
# Form(FormMeta("NewBase", (BaseForm,), {}))
# Form(NewBase(BaseForm))
class Form(with_metaclass(FormMeta, BaseForm)): Meta = DefaultMeta def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs): meta_obj = self._wtforms_meta()
# Meta()Meta的实例
if meta is not None and isinstance(meta, dict): meta_obj.update_values(meta)
super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix) for name, field in iteritems(self._fields):
# Set all the fields to attributes so that they obscure the class
# attributes with the same names.
setattr(self, name, field)
self.process(formdata, obj, data=data, **kwargs) def __setitem__(self, name, value):
raise TypeError('Fields may not be added to Form instances, only classes.') def __delitem__(self, name):
del self._fields[name]
setattr(self, name, None) def __delattr__(self, name):
if name in self._fields:
self.__delitem__(name)
else:
# This is done for idempotency, if we have a name which is a field,
# we want to mask it by setting the value to None.
unbound_field = getattr(self.__class__, name, None)
if unbound_field is not None and hasattr(unbound_field, '_formfield'):
setattr(self, name, None)
else:
super(Form, self).__delattr__(name) def validate(self):
"""
Validates the form by calling `validate` on each field, passing any
extra `Form.validate_<fieldname>` validators to the field validator.
"""
extra = {}
for name in self._fields:
inline = getattr(self.__class__, 'validate_%s' % name, None)
if inline is not None:
extra[name] = [inline] return super(Form, self).validate(extra)
2.Form的继承类
def with_metaclass(meta, base=object):
print(FormMeta("NewBase", (BaseForm,), {}))
return meta("NewBase", (base,), {})
它的返回值是继承type的一个元类,所以
class Form(FormMeta("NewBase", (BaseForm,), {}))
class Form(NewBase(BaseForm))
3.创建类的同时变质性创建该元类的init方法
class FormMeta(type):
def __init__(cls, name, bases, attrs):
type.__init__(cls, name, bases, attrs)
cls._unbound_fields = None
cls._wtforms_meta = None
成为创建form组件类的静态字段
# LoginForm._unbound_fields = None
# LoginForm._wtforms_meta = None
class LoginForm(Form):
name = simple.StringField(
实例化
1.首先执行的是元类的call方法
class FormMeta(type):
def __call__(cls, *args, **kwargs): if cls._unbound_fields is None:
fields = []
for name in dir(cls):
if not name.startswith('_'):
unbound_field = getattr(cls, name)
if hasattr(unbound_field, '_formfield'):
fields.append((name, unbound_field))
# We keep the name as the second element of the sort
# to ensure a stable sort.
fields.sort(key=lambda x: (x[1].creation_counter, x[0]))
cls._unbound_fields = fields # Create a subclass of the 'class Meta' using all the ancestors.
if cls._wtforms_meta is None:
bases = []
for mro_class in cls.__mro__:
print(mro_class)
if 'Meta' in mro_class.__dict__:
bases.append(mro_class.Meta)
print(tuple(bases))
cls._wtforms_meta = type('Meta', tuple(bases), {})
return type.__call__(cls, *args, **kwargs)
2.此时cls._wtforms_meta便是一个有type创建的类,
cls._unbound_fields是类中所有字段的列表
cls._unbound_fields = fields
cls._wtforms_meta = type('Meta', tuple(bases), {})
3.接下来执行的是Form的init方法
class Form(with_metaclass(FormMeta, BaseForm)):
def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs): meta_obj = self._wtforms_meta()
# Meta()Meta的实例
if meta is not None and isinstance(meta, dict): meta_obj.update_values(meta)
super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix) for name, field in iteritems(self._fields):
# Set all the fields to attributes so that they obscure the class
# attributes with the same names.
setattr(self, name, field)
self.process(formdata, obj, data=data, **kwargs)
把Meta类实例为对象 meta_obj = self._wtforms_meta(),接下来执行父类的init方法,参数分别是form字段列表,meta对象和前缀
super(Form, self).__init__(self._unbound_fields, meta=meta_obj, prefix=prefix)
class BaseForm(object): def __init__(self, fields, prefix='', meta=DefaultMeta()): if prefix and prefix[-1] not in '-_;:/.':
prefix += '-' self.meta = meta
self._prefix = prefix
self._errors = None
self._fields = OrderedDict() if hasattr(fields, 'items'):
fields = fields.items() translations = self._get_translations()
extra_fields = []
if meta.csrf:
self._csrf = meta.build_csrf(self)
extra_fields.extend(self._csrf.setup_form(self)) for name, unbound_field in itertools.chain(fields, extra_fields):
options = dict(name=name, prefix=prefix, translations=translations)
field = meta.bind_field(self, unbound_field, options)
self._fields[name] = field
。。。。。。
4.name = simple.StringField() 为LoginForm类的静态字段,该字段是类的一个实例对象,并接受很多参数
class StringField(Field): widget = widgets.TextInput() def process_formdata(self, valuelist):
if valuelist:
self.data = valuelist[0]
else:
self.data = '' def _value(self):
return text_type(self.data) if self.data is not None else ''
他继承的是一个Field类
class Field(object):
"""
Field base class
"""
errors = tuple()
process_errors = tuple()
raw_data = None
validators = tuple()
widget = None
_formfield = True
_translations = DummyTranslations()
do_not_call_in_templates = True # Allow Django 1.4 traversal def __new__(cls, *args, **kwargs):
if '_form' in kwargs and '_name' in kwargs:
return super(Field, cls).__new__(cls)
else:
return UnboundField(cls, *args, **kwargs)
首先执行的便是new方法,返回的是 self = return UnboundField(cls, *args, **kwargs)
5.执行UnboundField类的静态字段和init方法
class UnboundField(object):
_formfield = True
creation_counter = 0 def __init__(self, field_class, *args, **kwargs):
UnboundField.creation_counter += 1
self.field_class = field_class
self.args = args
self.kwargs = kwargs
self.creation_counter = UnboundField.creation_counter
创建计数每有一个form字段计数加一
6.回过来执行Field的init方法
class Field(object):
def __init__(self, label=None, validators=None, filters=tuple(),
description='', id=None, default=None, widget=None,
render_kw=None, _form=None, _name=None, _prefix='',
_translations=None, _meta=None): if _translations is not None:
self._translations = _translations if _meta is not None:
self.meta = _meta
elif _form is not None:
self.meta = _form.meta
else:
raise TypeError("Must provide one of _form or _meta") self.default = default
self.description = description
self.render_kw = render_kw
self.filters = filters
self.flags = Flags()
self.name = _prefix + _name
self.short_name = _name
self.type = type(self).__name__
self.validators = validators or list(self.validators) self.id = id or self.name
self.label = Label(self.id, label if label is not None else self.gettext(_name.replace('_', ' ').title())) if widget is not None:
self.widget = widget for v in itertools.chain(self.validators, [self.widget]):
flags = getattr(v, 'field_flags', ())
for f in flags:
setattr(self.flags, f, True)
wtforms源码流程的更多相关文章
- Flask之wtforms源码分析
一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...
- Flask 源码流程,上下文管理
源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...
- ES6.3.2 index操作源码流程
ES 6.3.2 index 操作源码流程 client 发送请求 TransportBulkAction#doExecute(Task,BulkRequest,listener) 解析请求,是否要自 ...
- Eureka服务端源码流程梳理
一.简述 spring cloud三步走,一导包,二依赖,三配置为我们简化了太多东西,以至于很多东西知其然不知其所以然,了解底层实现之后对于一些问题我们也可以快速的定位问题所在. spring clo ...
- django-admin的源码流程
一.admin的源码流程 首先可以确定的是:路由关系一定对应一个视图函数 a.当点击运行的时候,会先找到每一个app中的admin.py文件,并执行 b.执行urls.py admin.site是什么 ...
- Django session 源码流程
流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...
- rest_framework解析器组件源码流程
rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...
- 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解
原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...
- Django Rest Framework框架源码流程
在详细说django-rest-framework源码流程之前,先要知道什么是RESTFUL.REST API . RESTFUL是所有Web应用都应该遵守的架构设计指导原则. REST是Repres ...
随机推荐
- c# 取本地ip地址
public static System.Net.IPAddress[] GetIpAddress() { string hostName = System.Net.Dns.GetHostName() ...
- mysql系列四、mySQL四舍五入函数用法总结
一.MySQL四舍五入函数ROUND(x) ROUND(x)函数返回最接近于参数x的整数,对x值进行四舍五入. 实例: 使用ROUND(x)函数对操作数进行四舍五入操作.SQL语句如下: mysql& ...
- ODOO引用Echarts数据展示
作为一个后端开发,首先想到的是将需要的数据进行处理反馈给前端. 具体如下: 然后就是专门的echarts模块(我这样写主要是因为echarts会用到的地方比较多,后续直接调用) 1. 2.echart ...
- https协议的接口测试
用jmeter测试https接口: 和传统的http协议套路不太一样. 注意细节: 1.取样器正常选择http请求,端口号:为443(具体根据接口文档我刚开始用的80端口所以错了) 2.请求方法,一定 ...
- RestTemplate -springwebclient
1 使用jar版本 - spring-web-4.3.8.RELEASE.jar 场景:backend,post请求远端,header中加入accessToken,用于权限控制 HttpHeaders ...
- 深入理解JS中的变量及变量作用域
JS的变量有两种,“全局变量”和“局部变量”. “全局变量”声明在函数外部,可供所有函数使用,(全局变量属于window)而“局部变量”声明在函数体内部,只能在定义该变量的函数体内使用. 1.全局变量 ...
- Type in Chakra
Type in Chakra Javascript是一个无类型的语言. 我们要讨论的类型是指Chakra内置的一些数据结构,这些结构维护了Object的信息. Type在一类Object中共享数据,使 ...
- ERP发货系统的修改(四十三)
产品添加批号后相应修改产品库存表中对应批次产品的数量: /// <summary> /// 产品添加批号后相应修改产品库存表中对应批次产品的数量 /// </summary> ...
- ERP产品销售发货--发货管理(四十一)
发货详细信息的业务实体视图: CREATE VIEW [dbo].[View_BioSendAppInfo] AS SELECT SendId, BillNo, Subject, DepartMent ...
- (第4篇)hadoop之魂--mapreduce计算框架,让收集的数据产生价值
摘要: 通过前面的学习,大家已经了解了HDFS文件系统.有了数据,下一步就要分析计算这些数据,产生价值.接下来我们介绍Mapreduce计算框架,学习数据是怎样被利用的. 博主福利 给大家赠送一套ha ...