Python-flask-wtforms Component Process Source code

Source: Internet
Author: User

The first thing to figure out is that the class is created by the Meta class. When the class class Foo:pass is defined (the class is also an object), the __init__ method of the type class or type derived class is executed, when Foo (): Executes the __call__ method of the Type class or type-derived class, in __call__ Method calls the __new__ method of the Foo class to create an object, and then executes the __init__ method to assign a property to the created object.

 fromFlaskImportFlask, render_template, request, redirect fromWtformsImportForm fromWtforms.fieldsImportCore fromWtforms.fieldsImportHTML5 fromWtforms.fieldsImport Simple fromWtformsImportWidgets fromWtformsImportValidatorsapp= Flask (__name__, template_folder='Templates') App.debug=True#0 define the LogonForm class classLoginForm (Form):
   #1 instantiation of the Stringfield class name=Simple . Stringfield (Label='User name', validators=[validators. datarequired (Message='the user name cannot be empty.'), validators. Length (min=6, Max=18, message='user name must be longer than% (min) d and less than% (max) d')], widget=widgets. TextInput (), render_kw={'class':'Form-control'}) PWD=Simple . Passwordfield (Label='Password', validators=[validators. datarequired (Message='The password cannot be empty.'), validators. Length (min=8, message='user name must be longer than% (min) d'), validators. Regexp (Regex="^ (? =.*[a-z]) (? =.*[a-z]) (? =.*\d) (? =.*[[email Protected]$!%*?&]) [A-za-z\[email protected]$!%*?&]{8,} ", Message='password At least 8 characters, at least 1 uppercase letters, 1 lowercase letters, 1 digits and a special character')], widget=widgets. Passwordinput (), render_kw={'class':'Form-control'} ) classMETA:CSRF=FalsedefValidate_pwd (self,*args,**Kwargs):Pass@app. Route ('/login', methods=['GET','POST'])deflogin ():ifRequest.method = ='GET':
     #2. Instantiate a LoginForm object form=LoginForm ()returnRender_template ('login.html', form=form)Else: Form= LoginForm (formdata=Request.Form)ifform.validate ():Print('the user submits the data through the format validation, the submitted value is:', Form.data)Else: Print(form.errors)returnRender_template ('login.html', form=form)defTest (): Form=LoginForm ()if __name__=='__main__': App.run ()

No. 0 Step:

We'll see what happens when we define the LoginForm class.

First we need to know another way of Metaclass:with_metaclass

another way to Metaclass:classMyType (type):def __init__(self,*args,**Kwargs):Print('xxxx') Super (mytype,self).__init__(*args,**Kwargs)def __call__(CLS, *args, * *Kwargs): obj= CLS.__new__(Cls,*args, * *Kwargs) cls.__init__(Obj,*args, **kwargs)#foo.__init__ (obj)            returnobjdefWith_metaclass (Base):returnMyType ("MyType", (base,), {})classFoo (With_metaclass (object)):def __init__(self,name): Self.name=name#Print Result: xxxx xxxx

So we went to the form and found another way to find Metaclass.

class Form (With_metaclass (Formmeta, BaseForm)):     Pass

Let's go see with_metaclass again.

def with_metaclass (meta, base=object):    return Meta ("newbase" , (base,), {})
Formmeta ("newbase", (baseform,), {}) # created a newbase class through Formmeta, Newbase class inherits the BaseForm class
# so you have no doubt why the Formmeta class can create classes? let's go to Formmeta class and see
class Formmeta (type):
Pass
#发现FormMeta继承了type类, so we solved the problem just now.

That means that the __init__ method of the Formmeta class was executed when the loginform was defined.

class Formmeta (type):     def __init__ (CLS, name, bases, attrs):        type. __init__ (CLS, name, bases, attrs)         = none        = None

After this step is complete, the LoginForm class has two properties:Cls._unbound_fields = None and Cls._wtforms_meta = none

1th Step: Instantiate the object of Stringfield class, first should go to Stringfield to find __new__ method

class Stringfield (Field):     Pass
# found No in the Stringfield class, then we go to the base class

classField (object):def __new__(CLS, *args, * *Kwargs):
#判断不成立, go else.if '_form' inchKwargs and '_name' inchKwargs:returnSuper (Field, CLS).__new__(CLS)Else:
#返回一个UnboundField对象returnUnboundfield (CLS, *args, **kwargs)
class Unboundfield (object):     = True    = 0    def__init__(self, field_class, *args, * *Kwargs):        + =        1 =        Field_class= args        = Kwargs        = Unboundfield.creation_counter    #这个数字, which will be sorted by this later.

When this is done, we know that LoginForm's name and PWD fields are equal to Unboundfield objects

2nd step: Instantiating an LoginForm object executes the Formmeta __call__ method

classFormmeta (type):def __call__(CLS, *args, * *Kwargs):ifCls._unbound_fields isNone:fields= []            #get all fields in the LoginForm class             forNameinchdir (CLS):if  notName.startswith ('_'):                    #gets the value of the fieldUnbound_field = GetAttr (CLS, name)#Unbound_field is a Unboundfield object                    ifHasattr (Unbound_field,'_formfield'):#_formfield = TrueFields.Append ((name, Unbound_field))#[("Name", Unboundfield object), ("pwd", Unboundfield object)]Fields.sort (key=LambdaX: (X[1].creation_counter, x[0]))#sorts the fields list based on the Creation_counter property of the Unboundfield objectCls._unbound_fields = Fields#loginform._unbound_fields = [("Name", Unboundfield object), ("pwd", Unboundfield object)]        ifCls._wtforms_meta isnone:bases= []             forMro_classinchCls.__mro__:#loops The tuple of the current class and base class                if 'Meta' inchMro_class.__dict__:#If there is a meta class in the class, add the meta class to the bases listBases.append (Mro_class. Meta) Cls._wtforms_meta= Type ('Meta', tuple (bases), {})#Loginform._wtforms_meta = A new meta class, which inherits all meta classes, has the advantage of being able to fetch any meta class in either LoginForm or LoginForm base class through the new meta class        returnType.__call__(CLS, *args, **kwargs)

Then go to the LoginForm or base class to find __new__ method, find none, then continue to find LoginForm or base class __intit__ method

Python-flask-wtforms Component Process Source code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.