Flask 第二课Flask路由、请求和会话
tags:
- Flask
- 2019千锋教育
categories:
- flask
- 视图
- 路由
- Request对象
- Response对象
- Session
- Cookie
- Flask-Session
文章目录
第一节 flask的路由
1. Flask 网络请求的流程
- Flask 有四大内置对象
- Request对象 request
- Session对象 session
- G对象 g
- Config对象
- 在模板中config
- 在python代码中app.config
2. 路由
- 路由: 将从客户端发送过来的请求分发到指定函数上
- route规则-传参写法<converter:variable name>,converter对变量进行约束
- 内置converter类型如下(可以自定义):
- string接收任何没有斜杠(‘\’)的文件(不设约束时默认)
- int 接收整型
- float 接收浮点型
- path 接收路径,可接收斜线(’/)
- uuid 只接受uuid字符串,唯一-码,一种生成规则
- any 可以同时指定多种路径,进行限定
- 例子: 下面是注册蓝图blue后的写法。若没有注册用app.route()
- 注意:
- 一个函数上面可以映射多个路由。
- 可以出现相同的两个路由不报错。访问时以第一个路由为主。
@blue.route('/')
def index():
#渲染模板和传参 {{ msg }}
#return render_template('index.html', msg="今天天气好")
return 'Hello Flask'
# 传 整型参数
@blue.route('/users/<int:id>/')
def users(id):
# 将参数约束为数值类型, 浏览器写其他参数报错
print(id)
return 'Get Int %s' % str(id)
# 传 字符串参数 不设约束时默认(string).
# 传空或者参数中有/ 。报错找不到。
@blue.route('/getinfo/<string:token>/')
def getinfo(token):
print(token)
return 'Get String Success %s' % (token)
# 传 路径参数
# 这里同样不能传空
@blue.route('/getpath/<path:address>/')
def getpath(address):
print(address)
return 'Get PATH Successs {}'.format(address)
# 传 UUID参数
@blue.route('/getuuid/<uuid:uu>/')
def getuuid(uu):
# 网上找一个uuid测试:d6132fce-910d-4261-85c3-e537ce055e05
print(uu)
return 'Get UUID Success {}'.format(uu)
# 传 any参数 穷举(只能选a或b)
@blue.route('/getany/<any(a,b):an>')
def getany(an):
print(an)
return 'Get Any Success {}'.format(an)
@blue.route('/getnotice/<string:notice>/')
@blue.route('/getnotice/<uuid:notice>/')
def getnotice(notice):
# 一个函数上面可以映射多个路由。
# 可以出现相同的两个路由不报错。访问时以第一个路由为主。
print(notice)
return 'Get notice Success %s' % (notice)
3. 视图函数的方法
- 默认支持GET HEAD OPTIONS, 其余请求不支持。
- 如想要支持别的请求,需要手动注册。
- methods中指定请求方法GET POST HEAD PUT DELETE
@blue.route('/', methods=['GET', 'POST'])
def index():
#渲染模板和传参 {{ msg }}
#return render_template('index.html', msg="今天天气好")
return 'Hello Flask'
- url for反向解析,根据函数名字,获取反向路径url for(‘函数名’,参数名=value)
- 有蓝图 蓝图 + 函数
- 没有蓝图 直接路由函数
# 重定向函数
@blue.route('/redirect/')
def red():
# 这种属于 硬编码
return redirect('/')
# 反向路由
@blue.route('/redirect1/')
def red1():
# 这种属于 反向解析
# 有蓝图 蓝图 + 函数
# 没有蓝图 直接路由函数
return redirect(url_for('blue.index'))
# 反向路由传参
@blue.route('/redirect2/')
def red2():
# 反向路由传参
return redirect(url_for('blue.getany', an='a'))
第二节 Flask请求和响应对象
1. flask的四大内置对象-Request对象
- 服务器在接收到客户端的请求后,会自动创建Request对象。由Flask框架创建,Request对象不可修改
- 它常见的属性
属性 | 属性的意义 |
---|---|
url | 完整请求地址 |
base url | 去掉GET参数的URL |
host url | 只有主机和端口号的URL |
path | 路由中的路径 |
method | 请求方法 |
remote addr | 请求的客户端地址 |
args | GET请求参数 |
form | 请POST请求参数 |
files | 文件上传 |
headers | 请求头 |
cookies | 请求中的cookie |
- get 它并不是get专属,所有请求都能获取这个参数
- form 直接支持put 和 patch
- ImmutableMultiDict类 是dict子类
- args和form都是ImmutableMultiDict的对象
- 与字典的区别,可以存在相同的键
- ImmutableMultiDict中数据获取方式dict[‘uname’]或dict.get()'uname) 推荐用get
- 获取指定key对应的所有值(因为相同的键可以对应不同值) dict.getlist(‘uname’)
# Request对象由Flask框架生成
@blue.route('/getrequest/')
def get_request():
print(request.host)
print(request.url)
if request.method == 'GET':
print('GET')
return 'Get request Success '
# args 接收GET请求参数
# http://127.0.0.1:5000/sendrequest/?user=Rock&password=rock1204
@blue.route('/sendrequest/')
def send_request():
# 列表下把参数变为元组
print(request.args) #ImmutableMultiDict([('user', 'Rock'), ('password', 'rock1204')])
print(type(request.args))
return 'Send request Success '
# form接收POST参数
# 用PostMan模拟请求
@blue.route('/sendrequest1/', methods=['GET', 'POST'])
def send_request1():
# POST方式时GET的的参数也能获取到
print(request.args)
print(type(request.args))
print(request.form)
print(type(request.form))
print(request.headers)
return 'Send request Success '
2. Response对象介绍
- Response对象:服务器返回会给客户端的数据。由程序员创建,返回Response对象的三种方式
- 直接返回字符串
- 直接返回Response对象
- 通过make_response (data, code) data返回的数据内容 code状态码
- 返回模板render_template()(本质第一个一样,它把HTML变成字符串)
- 重定向
- redirect()
- 反向解析url_for(‘函数名’, 参数=value)
- 终止执行: 主动终止abort(code)
- 捕获异常: 提升交互让程序变得友好
@app.errorhandler(404)
def handler_error(error):
return 'Error'
# Response 对象
@blue.route('/getresponse/')
def get_response():
# return 'Hello sleeping ', 404 # 返回状态码404
# result = render_template('HelloURL.html')
# print(result)
# print(type(result))
# return result
# response = make_response('<h1>帅吗?</h1>')
# print(response, type(response)) #<Response 18 bytes [200 OK]> <class 'flask.wrappers.Response'>
abort(404) #终止请求
response = Response('自己造一个Response')
return response
@blue.errorhandler(404)
def handler_error(error):
print(error)
print(type(error))
return 'What'
第三节 flask的会话机制
- 跨请求共享数据
- 出现原因
- web开发中http都是短连接(connection:keepAlive)
- http请求是无状态的
- 请求从request到response就结束了(请求声明周期)
- Cookie
- 客户端会话技术
- 数据存储在客户端
- key-value
- flask默认对cookie 进行处理,支持中文。
- Session
- 数据存储在服务器
- key-value存储
- 对数据进行序列化
- 还进行了base64
- 还进行了zlib压缩
- 还传递了hash
- 最后Flask中将session数据存储在cookie中
- Token
1. Cookie
@blue.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
username = request.form.get('username')
response = Response('登录成功%s' % username)
# 设置Cookie
response.set_cookie('username', username)
return response
# 获取cookie中的信息
@blue.route('/mine/')
def mine():
username = request.cookies.get('username')
return '欢迎回来'
2. Session
- 运行报错没有设置secret key。到配置文件中加入: SECRET_KEY = “d6132fce-910d-4261-85c3-e537ce055e05”
- 这个值可以随便写,越复杂越安全
@blue.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
username = request.form.get('username')
response = Response('登录成功%s' % username)
# 设置Cookie
#response.set_cookie('username', username)
# 设置Session
# 报错The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
session['username'] = username
return response
# 获取cookie中的信息
@blue.route('/mine/')
def mine():
username = session.get('username')
return '欢迎回来'
- 服务器关闭,重启后。发现session依然存在。这是因为Flask中将session数据处理后存储在cookie中。
3. Flask-Session
- 上面我们知道Flask默认把session存在了cookie中。这种方式不好
- 我们想要让session存储到我们的服务器上,所以可以用Flask-Session库。
- 安装:pip install Flask-Session -i https://pypi.douban.com/simple
- 配置Flask-Session
- 在settings.py中配置。SESSION_TYPE = ‘redis’ # 把Session存到redis中
- 在ext.py中注册配置。from flask_session import Session Session(app)
- 再次运行上述代码:
- 可以发现session已经不存在cookie中了,它存在我们的redis中
- 在电脑上其他浏览器也可以访问session
- 可以指定过期时间。默认31天。写在settings.py中。PERMANENT_SESSION_LIFETTME
- 配置Session安全。SESSION_ COOKIE_ SECURE = True
- SESSION_TYPE 默认为null。
- null: NullSessionInterface (default)
- redis: RedisSessionInterface
- memcached: MemcachedSessionInterface
- filesystem: FileSystemSessionInterface
- mongodb: MongoDBSessionInterface
- sqlalchemy: SqlAlchemySessionInterface
- 不想别人直接看到Sessionid保证安全。它也是用设置中secret_key进行签名的。 SESSION USE_ SIGNER =True
- SESSION_REDIS(默认配置本机redis): 可选择其他的redis
- 最大保存session数SESSION_FILE_THRESHOLD. 默认为500个