flask(3.0)

一.Flask - CBV

from flask import Flask, render_template, url_for, views

app = Flask(__name__)

class Login(views.MethodView):
    def get(self, *args, **kwargs):
        print(url_for('my_login'))	# 通过my_login进行反向解析
        return render_template('login.html')
    def post(self, *args, **kwargs):
        return 'login success'

app.add_url_rule('/login', view_func=Login.as_view('my_login'))

if __name__ == '__main__':
    app.run(debug=True)

注意: 视图类中定义了哪些方法, 就可以允许哪种方式的请求, 也可以通过指定参数methods=["GET","POST"], 指定参数时可以在视图类中指定, 也可以在add_url_rule方法中指定.

二.Flask - Session

我们使用过flask内置的session,知道它是把session存放在浏览器,即客户端。今天要学习的flask-session是flask的第三方组件,看一下它和flask内置的session有什么不同以及它的使用方法。

flask-session是flask框架的session组件,flask内置session使用签名cookie保存,而该组件则将支持session保存到多个地方,如:

- redis
- memcached
- filesystem
- mongodb
- sqlalchmey

1.安装flask-session

pip3 install flask-session

2.回顾flask自带的session的使用方法

from flask import Flask, session

app = Flask(__name__)

app.secret_key = '~!@#$%'  # 配置session反向解析的秘钥


@app.route('/index')
def index():
    session['user'] = 'value'
    return 'hello'


if __name__ == '__main__':
    app.run(debug=True)

启动该程序, 使用浏览器访问http://127.0.0.1:5000, 可看到如下session:

3.flask-session的使用(以保存到redis为例)

from flask import Flask, session
from flask_session import Session  # 导入flask-session中的Session类
from redis import Redis

app = Flask(__name__)
# 对实例进行配置
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1', port=6379, db=6)

Session(app)  # 把原来app中的session进行替换


@app.route('/index')
def index():
    session['user'] = 'value'
    return 'hello'


if __name__ == '__main__':
    app.run(debug=True)

启动程序, 浏览器访问http://127.0.0.1:5000, 找到浏览器Cookie中的键值对:

使用cmd控制台打开redis客户端, 进行如下操作:

三.WTForms组件

WTForms是flask的组件, 类似于django的modelform组件.

1.安装

pip3 install wtforms

2.使用(以登录注册为例)

wtf.py文件:

from flask import Flask, render_template, request
from wtforms.fields import simple, core
from wtforms import Form, validators

app = Flask(__name__, template_folder="./app01/templates")


# Form组件: 注册类
class RegForm(Form):
    username = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='该字段不能为空'),
            validators.Length(min=3, max=10, message='用户名必须3-10个字符')
        ],
        id='user_id',
        render_kw={'class': 'user_name'}
    )
    password = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='该字段不能为空'),
            validators.Length(min=6, max=12, message='密码必须6-12个字符')
        ],
        id='pwd',
        render_kw={'class': 'pwd'}
    )
    repassword = simple.PasswordField(
        label='确认密码',
        validators=[
            validators.EqualTo(fieldname='password', message='两次密码不一致'),
        ],
        id='re_pwd',
        render_kw={'class': 're_pwd'}
    )
    email = simple.StringField(
        label='邮箱',
        validators=[
            validators.DataRequired(message='该字段不能为空'),
            validators.Email(message='必须符合邮箱格式')
        ],
        id='email',
        render_kw={'class': 'email'}
    )
    gender = core.RadioField(
        label='性别',
        coerce=int,  # 提交的数据类型,即1或2的数据类型(如下所示)
        choices=(
            (1, '女'),  # 元组第一个元素是value, 第二个元素是显示的值
            (2, '男')
        ),
        default=1  # 默认值为1
    )
    hobby = core.SelectMultipleField(
        label='爱好',
        validators=[
            validators.Length(min=1, max=3, message='爱好的数量为1-3个'),
        ],
        coerce=str,  # 注意,类型为str时,下面choices中每个元组第一个值必须带引号
        choices=(
            ('1', '健身'),
            ('2', '游泳'),
            ('3', '旅游'),
            ('4', '摄影'),
        ),
        default=('1', '3')  # 默认选中两个
    )
    # button = simple.SubmitField   # 渲染提交按钮


# Form组件: 登录类
class LoginForm(Form):
    username = simple.StringField(
        label='用户名',
        validators=[  # 校验条件,可迭代条件,因为可能校验多个条件
            validators.DataRequired(message='该字段不能为空'),
            validators.Length(min=3, max=10, message='用户名必须3-10个字符')
        ],
        description='this is a description',  # 描述标记
        id='user_id',  # 标签id
        widget=None,  # 默认组件(比如input type='text')在StringField中已经被实例化了
        render_kw={'class': 'my_login'}  # 添加属性和值
    )
    password = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='该字段不能为空'),
            validators.Length(min=6, max=12, message='密码必须6-12个字符')
        ],
        description='this is a description',
        id='pwd',
        default=None,
        render_kw={'class': 'pwd'}
    )

# 视图函数: 注册
@app.route('/reg', methods=['GET', 'POST'])
def reg():
    if request.method == 'GET':
        rf = RegForm()  # 实例化Form组件
        return render_template('register.html', wtf=rf)
    else:
        rf = RegForm(request.form)
        if rf.validate():   # 校验成功
            return rf.data.get('username')
        else:   # 校验失败
            print(rf.data)
            print(rf.errors)
            return render_template('register.html', wtf=rf)

# 视图函数: 登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        lf = LoginForm()    # 实例化Form组件
        return render_template('login.html', wtf=lf)
    else:
        lf = LoginForm(request.form)    # 将用户提交的数据传入组件中
        if lf.validate():   # 校验用户提交的数据
            return lf.data.get('username')  # 正确的数据在lf.data中
        else:   # 校验失败,错误的数据在lf.errors中
            return render_template('login.html', wtf=lf)


if __name__ == '__main__':
    app.run(debug=True)

register.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<form action="" method="post" novalidate>
    {% for field in wtf %}
        <p>
            {{ field.label }}
            {{ field }}
            {{ field.errors.0 }}
        </p>
    {% endfor %}
    <input type="submit" value="注册">
</form>
</body>
</html>

login.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form action="" method="post" novalidate>
    <p>
        {{ wtf.username.label }}
        {{ wtf.username }}{{ wtf.username.errors.0 }}
    </p>
    <p>
        {{ wtf.password.label }}
        {{ wtf.password }}{{ wtf.password.errors.0 }}
    </p>
    <input type="submit" value="登录">
</form>
</body>
</html>
posted @ 2019-03-03 17:46  咕噜噜~  阅读(514)  评论(0编辑  收藏  举报