iT邦幫忙

0

wtforms 原碼流程 (I)

一般 wtforms 的使用方法,建一個類( class )繼承 Form
example:

from wtforms import Form, StringField, validators, ValidationError

class ActionForm(Form):
    action = StringField('action', [validators.Required()])

Form 繼承 FormMeta("NewBase", (BaseForm), {})
FormMeta 繼承 type

class Form(with_metaclass(FormMeta, BaseForm)):
class Form(FormMeta("NewBase", (BaseForm), {})):
    pass
class FormMeta(type):
    pass
FormMeta("NewBase", (BaseForm), {})

等價於

class NewBase(BaseForm):
    pass

小結

Form 繼承於 NewBase
NewBase 利用 metaclass 的方式繼承於 BaseForm
利用 FormMeta __call__ 時會多創建 _unbound_fields (list) & _wtforms_meta (subclass)

不直接繼承 BaseForm 而透過 FormMeta 繼承

續 ...

example:

from wtforms import Form, StringField, validators, ValidationError

class ActionForm(Form):
    action = StringField('action', [validators.Required()])

創建 ActionForm 時,產生 _unbound_fields (list) & _wtforms_meta (subclass)


一般利用Field建制表單的輸入
example:

action = StringField('action', [validators.Required()])
class StringField(Field):
    widget = widgets.TextInput()
    pass

widget 用來產生 html 原碼

class Field(object):
    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)

Field 在初始化(__init__)前會被創建(__new__),創建時若輸入 (kwargs) 中不含有 _form and _name 則不會創建 Field 而是創建 UnboundField

小結

ActionForm 被初始化後,裡面有

  • _unbound_fields (list)
  • _wtforms_meta (subclass)
  • UnboundField('action', [validators.Required()])

尚未有邦友留言

立即登入留言