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)(?=.*[[email protected]$!%*?&])[A-Za-z\[email protected]$!%*?&]{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‘}
    )

原文地址:https://www.cnblogs.com/seven-007/p/8407070.html

时间: 2024-09-30 07:03:38

python之路_flask框架_flask-session组件、信号及wtforms组件的相关文章

python之路_flask框架_flask框架基础(2)

一.配置文件 和django不同的是,django会为我们提供配置好的setting文件,我们需要的配置都可以自动添加在setting文件中即可,但是flask不是这样,它是通过在内部为我们提供多种配置文件的接口,我们按照接口配置相关配置.简单介绍如下几种: 方式一: 如下,是我们入门告诉大家的配置方式,可以看出config本质上是一个字典(内部继承dict或者有__setitem__方法),通过给字典添加键值对的方式可以实现配置,但是像这种方式把大幅的配置代码写在主要程序代码中,显然不符合编程

python之路_day71_django分页及session介绍

一.django分页 如下实例为自定义分页: """ 分页组件使用示例: def index(request): obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info) page_user_list = USER_LIST[obj.start:obj.end] page_html = obj.page_html() return render(request,'index.htm

Python之路【第十八篇】:Web框架们

Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. 1 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.org/bottle.py Bottle框架大致可以分为以下部分: 路

App 组件化/模块化之路——Android 框架组件(Android Architecture Components)使用指南

面对越来越复杂的 App 需求,Google 官方发布了Android 框架组件库(Android Architecture Components ).为开发者更好的开发 App 提供了非常好的样本.这个框架里的组件是配合 Android 组件生命周期的,所以它能够很好的规避组件生命周期管理的问题.今天我们就来看看这个库的使用. 通用的框架准则 官方建议在架构 App 的时候遵循以下两个准则: 关注分离 其中早期开发 App 最常见的做法是在 Activity 或者 Fragment 中写了大量

Python之路【第十五篇】:Web框架

Python之路[第十五篇]:Web框架 Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/usr/bin/env python #coding:utf-8   import socket   def handle_request(client):     buf = client.recv(10

Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. Memc

Python之路【第十九篇】:爬虫

Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. Requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务. import

Python之路【第十七篇】:Django之【进阶篇】

Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')

Python之路【第十七篇】:Django【进阶篇】

Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')