web框架——flask-路由/视图-http请求与响应/会话控制
大纲:
1.flask框架理解
flask的组成
flask werkzeug wsgi 三者关系
基于flask快速搭建网站格式
2.站点配置项
3.路由
url
url参数的限制
methods
endpoint
redirect_to
4.视图
加装饰器
利用url_for实现重定向
与路由的联系/区别
5.http请求与响应
flask生命周期
请求(request相关属性方法)
响应
3种返回响应写法
Response对象相关属性方法
6.http会话控制
Cookie
Session
闪现
flask框架理解
- flask的组成
核心组成 :路由 / 视图 / 模板(jinja2)/ 请求与响应 / 会话管理(主要是session)/ 错误处理 / 上下文机制
扩展 :Flask-SQLAlchemy(ORM工具 简化数据库操作)等
- flask werkzeug wsgi 三者关系
flask是基于werkzeug构建的上层框架,而werkzeug是遵循wsig协议的工具库
- 基于flask快速搭建网站格式
"""基于flask快速搭建网站"""
from flask import Flask
app = Flask(__name__)
@app.route('/login',methods=['GET','POST'])
def login():
return 'xxx'
if __name__ == '__main__':
app.run()
站点配置项(设置配置项)
将站点配置写在config文件下,主文件引入:app.config.from_object('config . 想要引入的类')
config . py文件:
class BaseConfig(object):
"""站点的基础配置"""
#快速找bug配置
DEBUG=False
#给站点数据进行加密钥
SECRET_KEY='adsfgfadsgadfgsad'
class ProductionConfig(BaseConfig):
"""生产环境下的站点配置"""
pass
class DevelopmentConfig(BaseConfig):
"""开发环境下的站点配置"""
DEBUG=True
class TestConfig(BaseConfig):
"""测试环境下的站点配置"""
pass
run.py文件:
from flask import Flask
app = Flask(__name__)
# 引入config文件下的开发环境站点配置类
app.config.from_object('config.DevelopmentConfig')
@app.route('/login',methods=['GET','POST'])
def login():
return 'xxx'
if __name__ == '__main__':
app.run()
路由
- url
@app.route('/login')
def login():
pass
#视图函数名通常和url名一致
- url参数的限制 / methods
@app.route('/login/<int:num>',methods=['GET','POST'])
def login(num):
return f'{num}'
- endpoint
@app.route('/login/<int:user_id>',methods=['GET','POST'],endpoint='nb')
def login(user_id):
#反向生成url
print(url_for('nb',user_id = user_id))
return f'{user_id}'
#endpoint给视图函数器别名
- redirect_to
@app.route('/login/',methods=['GET','POST'],endpoint='nb')
def login():
return 'hhh'
@app.route('/xx',redirect_to='/login')
def xx():
pass
#redirect_to写在路由
#redirect写在视图函数
视图
- 加装饰器
import functools
...
def wrapper(func):
#将被装饰函数的元信息复制到装饰器内部定义的新函数中,避免元信息丢失
#需要导入functools模块 import functools
@functools.wraps(func)
def inner(*args,**kwargs):
print('before')
return func(*args,**kwargs)
return inner
@app.route('/login/',methods=['GET','POST'])
#若没有functools.wraps(func)则login__name__=inner 此装饰器装饰多个视图函数时视图函数的函数名均为inner,则利用视图函数反向生成url时视图函数名均为由inner
#若加了则即使装饰多个视图函数,元信息被保留即inner__name__=原函数名,则反向生成url时是url_for(原函数名)
@wrapper
def login():
return '1'
- 利用url_for实现重定向
def wrapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
print('before')
return func(*args,**kwargs)
return inner
@app.route('/login/',methods=['GET','POST'])
@wrapper
def login():
return '1'
@app.route('/xx')
def xx():
return redirect(url_for('login'))
- 与路由的联系/区别

http请求与响应
- flask生命周期


- 请求(request相关属性方法)
#前提
from flask import Flask, request


属性/方法
import json
from flask import Flask,request
app = Flask(__name__)
app.config.from_object('settings.DevelopmentConfig')
@app.route('/login',methods=['POST'])
def login():
"""
大纲:
接收http请求
单个:get
多个:getlist
"""
"""获取查询字符串"""
# #单个 http://127.0.0.1:5000/login?username=guohan&fav=tv
# username = request.args.get('username')
# fav = request.args.get('fav')
# print(username,fav)
# guohan ['tv']
#
# #多个 http://127.0.0.1:5000/login?username=guohan&fav=tv&fav=tt&fav=bb
# username = request.args.get('username')
# fav = request.args.getlist('fav')
# print(username,fav)
# guohan ['tv', 'tt', 'bb']
"""获取表单数据 不含文件"""
# #单个
# username = request.form.get('username')
# fav = request.form.get('fav')
# print(username,fav)
#
# #多个
# username = request.form.get('username')
# fav = request.form.getlist('fav')
# print(username,fav)
"""获取表单数据 含文件并保存"""
# pc = request.files.get('pc')
# pc.save(r'./1.png')
"""获取请求体中json格式的数据"""
# #直接获取请求体中json格式数据并转换成py中对应数据类型 类似fetchAPI中Response对象.json()
# print(request.json)
#
# #先获取原始json格式数据然后再手动转换成py中对应数据类型
# data = request.data
# print(json.loads(data))
"""获取请求头相关信息"""
print(request.headers.get('Content-Type'))
return 'hello'
if __name__ == '__main__':
app.run()
- 响应(response相关属性方法)
3种返回响应写法
#返回响应3种写法本质都是Response对象
#1 以元组形式返回
#格式 return 合法响应内容,状态码,响应头
#示例1
return render_template('./login.html'),200
#示例2:响应json格式数据
data = {'name':'guohan','age':22}
#写法1
return json.dumps(data),200,{'Content-Type':'application/json'}
#写法2 引入jsonify(flask下)
return jsonify(data)
#示例3:响应其他格式数据
with open('1.png','rb') as f:
res = f.read()
return res,200,{'Content-Type':'image/png'}
#2 通过make_response()返回Response对象
#前提: from flask import Flask, make_response
response = make_response(render_template('./login.html'),200)
return response
#3 直接返回Response对象
#前提: from flask import Flask, Response
return Response(render_template('./login.html'),200)
response相关属性方法
#2 以make_responser()/Response()返回时,Response对象的属性及方法
data = {'name':'guohan','age':22}
response = make_response(json.dumps(data))
#属性/方法
#状态码
response.status_code = 200
#响应头
response.headers['Content-Type'] = 'application/json'
#设置Cookie
#格式 Response对象.set_cookie('key','value')
response.set_cookie('user_id','2')
#删除cookie
#格式 Response对象.delete_cookie('key')
response.delete_cookie('user_id')

http会话控制

- Cookie(在客户端存储信息,不同域名Cookie不同)

response = make_response(render_template('./login.html'))
#设置Cookie
#格式 Response对象.set_cookie('key','value',max_age=xxx s)
# max_age指Cookie的有效时间,以s为单位,若不设置Cookie则是在关闭浏览器后失效
response.set_cookie('user_id','2',max_age=3600)
#删除cookie
#格式 Response对象.delete_cookie('key')
response.delete_cookie('user_id')
return response
- Session(在服务端存储信息/加密后存于Cookie)
flask中session数据加密后会放在cookie中,后面随请求发送到服务器
Session用法(增删改查)类比字典
#前提1
from flask import Flask,session


配置文件下的SECRET_KEY
#config.py文件
class BaseConfig(object):
"""
站点寄出配置
"""
DEBUG = False
SECRET_KEY = 'sfadfhskfhdkjshf'
class ProductionConfig(BaseConfig):
"""
生产环境下站点基础配置
"""
pass
class DevelopmentConfig(BaseConfig):
"""
开发环境下站点基础配置
"""
DEBUG = True
class TestConfig(BaseConfig):
"""
测试环境下站点基础配置
"""
pass
#mian.py文件
from flask import Flask, session
app = Flask(__name__)
app.config.from_object('config.xxxConfig')
- 闪现(flash)
是在一次请求中存储临时消息,仅供下一次请求显示的机制,显示后会自动销毁,依赖Session(即必须配置SECRET_KEY)
使用步骤:
#初始化配置
from flask import Flask
app = Flask(__name__)
app.config['SECRET_KEY'] = 'asdfsfasadfsa'
#存储闪现消息
from flask import Flask, flash
...
@app.route('index1')
def index():
flash('密码错误',category='error')
格式:
flash(消息内容,分类标识)
#显示闪现消息
from flask import Flask, flash, get_flashed_messages
...
获取格式:
通过get_flashed_messages()获取,返回一个列表结构,格式随是否带分类变化
#不带分类
get_flashed_messages() ——> [消息1,消息2,消息3...]
#带分类
get_flashed_messages(with_categories=true) ——> [(类别1,消息1),(类别2,消息2),(类别3,消息3)...]
#筛选特定分类的消息
get_flashed_messages(category_filter=['类别1','类别2']) ——> [消息1,消息2]
get_flashed_messages(with_categories=true,category_filter=['类别1','类别2']) ——> [(类别1,消息1),(类别2,消息2)]
Flask闪现消息模板渲染
# main。py
from flask import Flask, flash, redirect, render_template
app = Flask(__name__,template_folder='../templates')
app.config['SECRET_KEY'] = 'asdfsfasadfsa'
@app.route('/login/',methods=['GET'])
def login():
return render_template('login.html')
@app.route('/admin',methods=['GET'])
def admin():
#模拟登录验证场景
flag = False #假设未登录
if not flag:
flash('请先登录!','error')
return redirect('/login')
else:
flash('已登录!', 'success')
return render_template('admin.html')
if __name__ == '__main__':
app.run(debug=True)
#base.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% block title %}base标题{% endblock %}</title>
</head>
<body>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category,mag in messages %}
<script>
alert('{{ mag }}')
</script>
{% endfor %}
{% endif %}
{% endwith %}
</body>
</html>
#login.html
{% extends 'base.html' %}
此随笔代码笔记
http请求 blog-static.cnblogs.com/files/blogs/853151/test2请求.js?t=1763532636&download=true
http响应 blog-static.cnblogs.com/files/blogs/853151/test3响应.js?t=1763532782&download=true
浙公网安备 33010602011771号