zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    NSString常用方法
    iOS8 【xcode6中添加pch全局引用文件】
    Size Classes with Xcode 6
    推荐学习网站
    Objective C类方法load和initialize的区别
    iOS开发中,单元测试的好处!
    iOS 9.0中UIAlertController的用法。
    iOS 9.0 数组中所有对象共同执行方法的接口不可用
    Xcode 7.0以后 iOS 9.0以后 最新百度地图 详细使用
    iOS9适配关于URL Schemes
  • 原文地址:https://www.cnblogs.com/ldq1996/p/8259788.html
Copyright © 2011-2022 走看看