未实例化前

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源码流程的更多相关文章

  1. Flask之wtforms源码分析

    一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...

  2. Flask 源码流程,上下文管理

    源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...

  3. ES6.3.2 index操作源码流程

    ES 6.3.2 index 操作源码流程 client 发送请求 TransportBulkAction#doExecute(Task,BulkRequest,listener) 解析请求,是否要自 ...

  4. Eureka服务端源码流程梳理

    一.简述 spring cloud三步走,一导包,二依赖,三配置为我们简化了太多东西,以至于很多东西知其然不知其所以然,了解底层实现之后对于一些问题我们也可以快速的定位问题所在. spring clo ...

  5. django-admin的源码流程

    一.admin的源码流程 首先可以确定的是:路由关系一定对应一个视图函数 a.当点击运行的时候,会先找到每一个app中的admin.py文件,并执行 b.执行urls.py admin.site是什么 ...

  6. Django session 源码流程

    流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...

  7. rest_framework解析器组件源码流程

    rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...

  8. 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

    原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...

  9. Django Rest Framework框架源码流程

    在详细说django-rest-framework源码流程之前,先要知道什么是RESTFUL.REST API . RESTFUL是所有Web应用都应该遵守的架构设计指导原则. REST是Repres ...

随机推荐

  1. plsql developer如何自定义快捷键

    首选项 用户界面 编辑器 自动替换 选择替换文件,文件内容: sf=select * from df=delete from

  2. PYTHON-匿名函数,递归与二分法,面向过程编程-练习

    # 四 声明式编程练习题 # 1.将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写names = ['egon', 'alex_sb', ' ...

  3. 使用 IIS 在 Windows 上托管 ASP.NET Core

    参考微软文档: https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/index?tabs=aspnetcore2x 将as ...

  4. SQL日期时间和字符串函数

  5. PHP中的10个实用函数

    1.php_check_syntax 这个函数可以用来检查特定文件中的PHP语法是否正确. <?php $error_message = ""; $filename = &q ...

  6. 设计模式【转自JackFrost的博客】

    首先,感谢作者对知识的分享 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样. 文章结构:1.单一职责原则( ...

  7. 【深度探索C++对象模型 | 02】构造函数语意学

    默认构造函数的构造操作.拷贝构造函数额构造操作  注意:默认构造函数和拷贝构造函数在必要时的时候由编译器产生出来. 参考资料 关于默认构造函数的几个错误认识(四种情况下,编译器会生成默认构造函数)

  8. Code alignment 代码对齐改进(VS2017)

    In mathematics you always keep your equals lined up directly underneath the one above. It keeps it c ...

  9. Codeigniter使用HMVC(一)

    涉及三方代码: https://tutorials.kode-blog.com/codeigniter-admin-panel https://bitbucket.org/wiredesignz/co ...

  10. 查看Windows系统里的进程已运行的时间

    搜索 ProcessExplorer ,可以去微软下载它.右键点击项类,selcet conlumns...在 Process Performance 里 选择start time.有了进程的启动时间 ...