python3-开发进阶Flask的基础(4)
2018-08-24 19:08
851 查看
今日内容:
上下文管理:LocalProxy对象
上下文管理: 请求上下文: request/session app上下文:app/g
第三方组件:wtforms 1、使用 2、原理
test.py
先思考几个问题:
1、form 对象为什么可以for循环?
变成一个可迭代对象,类中含有__iter__,并且返回一个迭代器
2、__new__方法返回值决定对象到底是什么
3、metaclass
创建类时,先执行type的__init__方法,当一个类实例化时,
执行type的__call__方法, 先执行类的__new__,创建对象再执行类的__init__,初始化
__call__方法的返回值就是实例化的对象
4、wtforms的实现
我们创建的类没有metaclass但他继承的父类,有指定metaclass,就按照父类的来创建类
看看FormMeta 中的__init__方法做了什么事?
实例化时先执行__new__
UnboundField类是做什么的?
做完自己的操作,再执行父类的__call__,然后type会调用自己__new__方法,__init__方法
下面Form 的序列化
源码:
类的创建 type.__init__
对象的创建 type.__call__ 1、类.__new__ 2、类.__init__
上下文管理:LocalProxy对象
上下文管理: 请求上下文: request/session app上下文:app/g
第三方组件:wtforms 1、使用 2、原理
一、LocalProxy
首先我们一看一段自己写的代码:#test.py DATA={ 'request':{ 'method':'GET', 'form':{} }, 'session':{ 'user':'duoduo', 'age':'20' } } class LocalProxy(object): # def __init__(self,key): self.key=key def get_dict(self): return DATA[self.key] def __str__(self): return 'duoduo' def __getattr__(self, item): data_dict=self.get_dict() return data_dict[item] def __getitem__(self, item): data_dict = self.get_dict() return data_dict[item] def __add__(self, other): return other+1 request=LocalProxy('request') session=LocalProxy('session')
LocalProxy的类就相当于一个代理
from flask import Flask,request,render_template,session,current_app,g,redirect from wtforms import Form from wtforms.fields import simple from wtforms.fields import html5 from wtforms.fields import core from wtforms import widgets from wtforms import validators app = Flask(__name__) class LoginForm(Form): name = simple.StringField( validators=[ validators.DataRequired(message='用户名不能为空.'), # validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d') ], widget=widgets.TextInput(), render_kw={'placeholder':'请输入用户名'} ) pwd = simple.PasswordField( validators=[ validators.DataRequired(message='密码不能为空.'), # validators.Length(min=8, message='用户名长度必须大于%(min)d'), # validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}", # message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符') ], render_kw={'placeholder':'请输入密码'} ) @app.route('/login',methods=['GET','POST']) def login(): if request.method == "GET": form = LoginForm() # print(form.name,type(form.name)) # form.name是StringField()对象, StringField().__str__ # print(form.pwd,type(form.pwd)) # form.pwd是PasswordField()对象,PasswordField().__str__ return render_template('login.html',form=form) form = LoginForm(formdata=request.form) if form.validate(): print(form.data) return redirect('https://www.luffycity.com/home') else: # print(form.errors) return render_template('login.html', form=form) class RegisterForm(Form): name = simple.StringField( label='用户名', validators=[ validators.DataRequired() ], widget=widgets.TextInput(), render_kw={'class': 'form-control'}, default='alex' ) pwd = simple.PasswordField( label='密码', validators=[ validators.DataRequired(message='密码不能为空.') ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} ) pwd_confirm = simple.PasswordField( label='重复密码', validators=[ validators.DataRequired(message='重复密码不能为空.'), validators.EqualTo('pwd', message="两次密码输入不一致") ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} ) email = html5.EmailField( label='邮箱', validators=[ validators.DataRequired(message='邮箱不能为空.'), validators.Email(message='邮箱格式错误') ], widget=widgets.TextInput(input_type='email'), render_kw={'class': 'form-control'} ) gender = core.RadioField( label='性别', choices=( (1, '男'), (2, '女'), ), coerce=int # int("1") ) city = core.SelectField( label='城市', choices=( ('bj', '北京'), ('sh', '上海'), ) ) hobby = core.SelectMultipleField( label='爱好', choices=( (1, '篮球'), (2, '足球'), ), coerce=int ) favor = core.SelectMultipleField( label='喜好', choices=( (1, '篮球'), (2, '足球'), ), widget=widgets.ListWidget(prefix_label=False), option_widget=widgets.CheckboxInput(), coerce=int, default=[1, ] ) @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'GET': form = RegisterForm() return render_template('register.html', form=form) form = RegisterForm(formdata=request.form) if form.validate(): print(form.data) return redirect('https://www.baidu.com') return render_template('register.html', form=form) import helper class UserForm(Form): city = core.SelectField( label='城市', choices=(), coerce=int ) name = simple.StringField(label='姓名') def __init__(self,*args,**kwargs): super(UserForm,self).__init__(*args,**kwargs) self.city.choices=helper.fetch_all('select id,name from tb1',[],type=None) @app.route('/user') def user(): if request.method == "GET": #form = UserForm(data={'name':'duoduo','city':3}) form = UserForm() return render_template('user.html',form=form) if __name__ == '__main__': app.run()
test.py
先思考几个问题:
1、form 对象为什么可以for循环?
变成一个可迭代对象,类中含有__iter__,并且返回一个迭代器
class Foo(object): # def __iter__(self): # return iter([11,22,33]) #值是11,22,33 def __iter__(self): yield 1 yield 2 yield 3 obj=Foo() for item in obj: print(item)
2、__new__方法返回值决定对象到底是什么
class Bar(object): def __init__(self,cls): self.cls=cls class Foo(object): def __new__(cls, *args, **kwargs): #return super(Foo,cls).__new__(cls,*args,**kwargs) <__main__.Foo object at 0x0000023741EEAC88> return Bar(cls) #<__main__.Bar object at 0x0000013FC1ABA4E0> obj=Foo() print(obj)
3、metaclass
创建类时,先执行type的__init__方法,当一个类实例化时,
执行type的__call__方法, 先执行类的__new__,创建对象再执行类的__init__,初始化
__call__方法的返回值就是实例化的对象
#类创建的两种方式 类是type创建的 #1、 # class Foo(object): # a1=123 # def func(self): # return 666 # Foo=type('Foo',(object,),{'a1':123,'func':lambda self:666}) #2、自定义type # # class MyType(type): # pass # # class Foo(object,metaclass=MyType): #指定当前类由谁创建 # a1=123 # def func(self): # return 666 # Foo=MyType('Foo',(object,),{'a1':123,'func':lambda self:666}) #3、metaclass 作用 #指定当前类由谁来创建 class MyType(type): def __init__(self,*args,**kwargs): super(MyType,self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): obj=cls.__new__(cls) cls.__init__(obj,*args, **kwargs) return obj class Foo(object,metaclass=MyType): a1=123 def __init__(self): pass def __new__(cls, *args, **kwargs): return object.__new__(cls) def func(self): return 666 #Foo是类 #Foo是MyType的一个对象 obj=Foo()
4、wtforms的实现
from wtforms import Form #先点开Form
我们创建的类没有metaclass但他继承的父类,有指定metaclass,就按照父类的来创建类
看看FormMeta 中的__init__方法做了什么事?
实例化时先执行__new__
UnboundField类是做什么的?
做完自己的操作,再执行父类的__call__,然后type会调用自己__new__方法,__init__方法
下面Form 的序列化
源码:
类的创建 type.__init__
对象的创建 type.__call__ 1、类.__new__ 2、类.__init__
相关文章推荐
- python3-开发进阶Flask的基础(5)
- python3-开发进阶Flask的基础(5)
- python3-开发进阶Flask的基础(3)
- python3-开发进阶Flask的基础(2)
- python3-开发进阶Flask的基础
- Python开发基础-Day22反射、面向对象进阶
- 2018年大神带你用Python零基础进阶课程入门爬虫flask实战
- Flask笔记:(Flask开发基础与入门)
- 基础入门_Python-模块和包.运维开发中chartdet编码检测的最佳实践?
- Python开发基础-Day33 IO模型
- python基础之类的进阶
- 今晚九点|Flask 基础与 Web 开发实战
- Python开发基础-Day4-布尔运算、集合
- python2加flask 开发web项目 房地产微官网
- python web开发-flask中带斜线/的url和不带斜线/的url区别详解
- [LINK]Python服务器开发一:python基础
- Python开发基础-Day5-字符编码、文件处理和函数基础(草稿)
- python3开发进阶-Django框架中的ORM的常用(增,删,改,查)操作
- Python开发基础-day2
- [Python入门及进阶笔记]Python-基础-列表及列表解析小结