一.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>

flask(3.0)的更多相关文章

  1. Airflow安装异常:ERROR: flask-appbuilder 1.12.3 has requirement Flask<2,>=0.12, but you'll have flask 0.11.1 which is incompatible.

    1 详细异常: ERROR: flask-appbuilder 1.12.3 has requirement Flask<2,>=0.12, but you'll have flask 0 ...

  2. [Python] Flask从0到1开发轻量级网页

    概述 Flask采用MVT模型,即Model, Template, View Model:定义数据的存储格式,并且提供了数据库访问的API View:定义那些数据被显示,是业务逻辑处理模块 Templ ...

  3. [py]flask从0到1-模板/增删改查

    flask知识点 1.后端渲染html到前端 render_template 2.后端获取前端数据 request.args.get 3.前端获取后端数据 模板 4.警示消息 flash {{ get ...

  4. flask(2.0)

    目录 一. Flask基础(一) 1.Flask启动 2.路由 3.Response 4.Request 5.Jinja2 6.session 二.Flask基础(二) 1.路由配置 (1)metho ...

  5. flask(1.0)

    目录 一. 关于KeyError和IndexError 二. Python三大主流框架对比 三. flask基础 1.安装flask 2.用flask写出的第一个页面 3.Flask的Response ...

  6. Flask:操作SQLite3(0.1)

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 本文介绍了第一次在Flask框架中操作SQLite3数据库的测试,参考了官网的文档Using SQLite 3 wit ...

  7. Flask:cookie 和 session (0.1)

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 Cookie是什么?有什么用? 某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上的数据(通常 ...

  8. Flask:静态文件&模板(0.1)

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 前面看了Flask的Quickstart文档,可是,一直没有练习里面的内容,这不,刚刚练习完毕,来写篇博文记录一下! ...

  9. Flask 发布 1.0 稳定版

    简评:现在都开始版本大跃进了吗?对,别看别人,说的就是你 pipenv(名单太长,待补齐...) Flask 其实早就已经十分稳定了,而在第一个 commit 大概 8 年之后,版本号才最终反映出了这 ...

随机推荐

  1. git 版本落后推送错误

     http://114.215.90.144/student_association/student.git ! [rejected]        master -> master (non- ...

  2. C#实现10进制转2进制

    这几天在复习计算机原理,看到二进制忽然想到二进制转10进制的公式,然后转念一想10进制转二进制的公式好像没印象,那索性自己写出来. 结果学渣的我发现,并不能写出来!什么数列,对数,xx函数忘得一干二净 ...

  3. golang embedded structs

    golang 中把struct 转成json格式输出 package main import ( "encoding/json" "fmt" ) type Pe ...

  4. 记一次基于 mpvue 的小程序开发及上线实战

    小程序名称:一起打车吧 项目地址: 客户端:https://github.com/jrainlau/taxi-together-client 服务端:https://github.com/jrainl ...

  5. bzoj1711[USACO07OPEN]吃饭Dining

    题意 有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有n头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮 ...

  6. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (LCT维护连通性)

    直接把x设为根,然后查询y所在联通块的根是不是x就行了. CODE #include <cstdio> #include <cstring> #include <algo ...

  7. CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

    按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...

  8. 删除3天前创建的以log结尾的文件

    1. #/bin/bash # filename: del_log.sh find / -name "*.log" -mtime 3 | xargs rm -rf 2. #/bin ...

  9. MySQL基础练习02---牛客网

    目录 1. 从titles表中获取title并按照title分组 2.从titles表中获取title并按照title分组,重复的emp_no忽略 3 查找employees表 4 统计平均工资 5 ...

  10. Luogu P4141 消失之物 背包 分治

    题意:给出$n$个物品的体积和最大背包容量$m$,求去掉一个物品$i$后,装满体积为$w\in [1,m]$背包的方案数. 有 N 个物品, 体积分别是 W1, W2, …, WN. 由于她的疏忽, ...