python之路_flask框架_flask-session组件信号及wtforms组件
Posted 骑猪走秀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之路_flask框架_flask-session组件信号及wtforms组件相关的知识,希望对你有一定的参考价值。
一、flask-session组件
我们知道,在flask的内置session中,是存到加密cookie中。但是我们怎样么才可以将session在服务器也保存呢?之前我们也说过,自定义的session可以将键值对保存在内存中,但是想要实现在服务端永久的保存起来,我们就可以利用flask-session组件。利用此组件可以将session保存在redis、文件memcache等,如下列出主要的使用配置。
1、redis保存
from flask import Flask,session from flask_session import Session import redis app=Flask(__name__) # 为Flask-session组件提供的配置 app.config[\'SESSION_TYPE\'] = \'redis\' # session类型为redis app.config[\'SESSION_REDIS\'] = redis.Redis(host=\'127.0.0.1\', port=\'6379\', password=\'123123\') # 用于连接redis的配置 app.config[\'SESSION_KEY_PREFIX\'] = \'session:\' # 保存到session中的值的前缀 app.config[\'SESSION_PERMANENT\'] = False # 如果设置为True,则关闭浏览器session就失效。 app.config[\'SESSION_USE_SIGNER\'] = False # 是否对发送到浏览器上 session:cookie值进行加密 Session(app) @app.route("/index/") def index(): session["k1"]="v1" #正常设置session return "ok" if __name__ == \'__main__\': app.run()
2、文件保存
from flask import Flask,session from flask_session import Session app=Flask(__name__) # 为Flask-session组件提供的配置 app.config[\'SESSION_TYPE\'] = \'filesystem\' # session类型为文件 app.config[\'SESSION_FILE_DIR\'] = r\'D:\\PycharmProjects\\flask_day05\\flask-session组件\' # 文件路径 app.config[\'SESSION_FILE_THRESHOLD\'] = 500 # 存储session的个数如果大于这个值时,就要开始进行删除了 app.config[\'SESSION_FILE_MODE\'] = 384 # 文件权限类型 app.config[\'SESSION_PERMANENT\'] = True # 如果设置为True,则关闭浏览器session就失效。 app.config[\'SESSION_USE_SIGNER\'] = False # 是否对发送到浏览器上session的cookie值进行加密 app.config[\'SESSION_KEY_PREFIX\'] = \'session:\' # 保存到session中的值的前缀 Session(app) @app.route("/index/") def index(): session["k1"]="v1" #正常设置session return "ok" if __name__ == \'__main__\': app.run()
3、memcache保存
主要配置如下,使用方式如上实例相同。
import memcache app.config[\'SESSION_TYPE\'] = \'memcached\' # session类型为memcached app.config[\'SESSION_PERMANENT\'] = True # 如果设置为True,则关闭浏览器session就失效。 app.config[\'SESSION_USE_SIGNER\'] = False # 是否对发送到浏览器上session的cookie值进行加密 app.config[\'SESSION_KEY_PREFIX\'] = \'session:\' # 保存到session中的值的前缀 app.config[\'SESSION_MEMCACHED\'] = memcache.Client([\'10.211.55.4:12000\']) Session(app)
二、信号
Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。它与flask中的特殊装饰器不同的地方在于,信号没有返回值,而特殊装饰器是可以有返回值的,且返回值是有意义 。利用信号可以降低代码之间的耦合。安装方式为:pip3 install blinker。
1、内置信号
如下列出了flask内置的10个信号,其中序号表示信号被触发的顺序。
10个信号: 2. request_started = _signals.signal(\'request-started\') # 请求到来前执行 5. request_finished = _signals.signal(\'request-finished\') # 请求结束后执行 3. before_render_template = _signals.signal(\'before-render-template\') # 模板渲染前执行 4. template_rendered = _signals.signal(\'template-rendered\') # 模板渲染后执行 2/3/4/5或不执行 got_request_exception = _signals.signal(\'got-request-exception\') # 请求执行出现异常时执行 6. request_tearing_down = _signals.signal(\'request-tearing-down\') # 请求执行完毕后自动执行(无论成功与否) 7. appcontext_tearing_down = _signals.signal(\'appcontext-tearing-down\')# 请求上下文执行完毕后自动执行(无论成功与否) 1. appcontext_pushed = _signals.signal(\'appcontext-pushed\') # 请求app上下文push时执行 8. appcontext_popped = _signals.signal(\'appcontext-popped\') # 请求上下文pop时执行 message_flashed = _signals.signal(\'message-flashed\') # 调用flask在其中添加数据时,自动执行
2、自定义信号
from flask import Flask from flask.signals import _signals app = Flask(__name__) mysignal= _signals.signal(\'mysignal\') #自定义信号 # 定义函数 def foo(*args,**kwargs): print(\'罗姑娘\',args,kwargs) # 定义函数 def bar(*args,**kwargs): print(\'少姑娘\',args,kwargs) # 将函数注册到自定义信号中: 添加到这个列表 mysignal.connect(foo) mysignal.connect(bar) @app.route(\'/index/\') def index(): # 触发这个信号:执行注册到列表中的所有函数 mysignal.send(000,a1=123,a2=456) #send为触发信号的方法,传自定义函数需要的参数 return "xx" if __name__ == \'__main__\': app.run()
三、wtforms组件
在django中我们熟悉了forms组件,利用他可以实现对表单数据的校验,我们将要介绍wtforms组件和django的forms组件相似,实现的功能是一样的。WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。安装如下:pip3 install wtforms,具体的使用分别以用户登录和注册实例介绍:
1、登录实例
后端代码:
from flask import Flask,render_template,request from wtforms import Form,widgets,validators from wtforms.fields import core,html5,simple app=Flask(__name__) class LoginForm(Form): name=simple.StringField( label="用户名", validators=[ validators.DataRequired(message="用户名不能为空"), validators.Length(min=6,max=10,message="用户名长度必须大于%(min)d,小于%(max)d") ], widget=widgets.TextInput(), render_kw={"class":"form-control"} ) password=simple.PasswordField( label="密码", # 设置验证信息 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个特殊字符\') ], widget=widgets.PasswordInput(), render_kw={\'class\': \'form-control\'} #给标签设置属性 ) @app.route(\'/login/\',methods=[\'GET\', \'POST\']) def login(): if request.method=="POST": form=LoginForm(request.form) if form.validate(): print(form.data) return "登陆成功" else: print(form.errors) return render_template("login.html",form=form) else: form=LoginForm() return render_template("login.html",form=form) if __name__ == \'__main__\': app.run()
前端代码:
2、注册实例
后端实例如下,包含可能需要渲染的标签类型。前端渲染方式如登录实例。
from flask import Flask,render_template,request from wtforms import Form,widgets,validators from wtforms.fields import core,html5,simple app=Flask(__name__) 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 ) 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, 2] ) def __init__(self, *args, **kwargs): super(RegisterForm, self).__init__(*args, **kwargs) self.favor.choices = ((1, \'篮球\'), (2, \'足球\'), (3, \'羽毛球\')) def validate_pwd_confirm(self, field): """ 自定义pwd_confirm字段规则,例:与pwd字段是否一致 :param field: :return: """ # 最开始初始化时,self.data中已经有所有的值 if field.data != self.data[\'pwd\']: # raise validators.ValidationError("密码不一致") # 继续后续验证 raise validators.StopValidation("密码不一致") # 不再继续后续验证 @app.route(\'/register/\',methods=[\'GET\', \'POST\']) def register(): if request.method=="POST": form=RegisterForm(request.form) if form.validate(): print(form.data) return "注册成功" else: print(form.errors) return render_template("register.html",form=form) else: form = RegisterForm(data={\'gender\': 1}) # 可以通过data设置默认值 return render_template("register.html" ,form=form) if __name__ == \'__main__\': app.run()
3、自定义校验类
参考源码中校验的实现的方式,我们也可以自己实现自定义校验规则,参考如下实例:
#自定义姓名是否为王浩的校验类
class MyValidator(object): def __init__(self,message): self.message = message def __call__(self, form, field): print(field.data) if field.data == \'王浩\': return None raise validators.StopValidation(self.message) class LoginForm(Form): name = simple.StringField( label=\'用户名\', validators=[ MyValidator(message=\'用户名必须等于王浩\') #自定义校验类的使用 validators.DataRequired(message=\'用户名不能为空.\'), validators.Length(min=6, max=18, message=\'用户名长度必须大于%(min)d且小于%(max)d\') ], widget=widgets.TextInput(), render_kw={\'class\': \'form-control\'} )
以上是关于python之路_flask框架_flask-session组件信号及wtforms组件的主要内容,如果未能解决你的问题,请参考以下文章
python之路_flask框架_flask-session组件信号及wtforms组件
python之路_flask框架_单例模式及session原理
python flask框架不执行if __name__ == '__main__'