flask基本使用
1.三种启动方式
from flask import Flask
# 1.创建app应用对象
app = Flask(__name__)
# 2.视图函数绑定路由信息
@app.route('/')
def index():
return "index page"
"""
Flask新版本运行方式-命令
export FLASK_APP=xxx.py
export FLASK_ENV=development
flask run -h ip -p port
"""
# 3.启动flask项目[1.x之后新版flask运行方式]
if __name__ == '__main__':
# 旧版运行方式
# app.run()
pass
2.路由
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
"""
通过app.route装饰器绑定路由信息
通过app.url_map属性查看路由信息:
ods设置请求方式:methods=["get", "POST"]
"""
# 忽略大小写
@app.route('/index', methods=["get", "POST"])
def index():
print(app.url_map)
return 'index page!'
# 需求:http://127.0.0.1:8000/user_id/66
# 语法:<变量名称> 等价于 <string:变量名称>
# 注意:变量名称和形参名称保持一致
@app.route('/user_id/<uid>')
def demo1(uid):
print(uid)
# 字符串类型
print(type(uid))
return "demo1"
# 需求:http://127.0.0.1:8000/userid_int/66 要求提取的参数必须是int类型
# 转换器语法:<转换器名称:变量名称>
# 转换器语法父类:BaseConverter
# int类型转换器语法:<int:变量名称>
# 注意:变量名称和形参名称保持一致
# 用途:验证路径是否按照符合的类型传递
@app.route('/userid_int/<int:uid>')
def demo2(uid):
print(uid)
print(type(uid))
return "demo2"
"""
FLASK源码自带的转换器
DEFAULT_CONVERTERS = {
"default": UnicodeConverter,
"string": UnicodeConverter,
"any": AnyConverter,
"path": PathConverter,
"int": IntegerConverter,
"float": FloatConverter,
"uuid": UUIDConverter,
}
"""
3.自定义路由转换器
# 需求:127.0.0.1:8000/mobile/18511112222
# 1.自定义转换器类继承于BaseConverter
class MobileConverter(BaseConverter):
# 2.重写regex属性,自定义正则匹配
# 不能匹配开头
regex = r"1[3-9]\d{9}$"
# 3.将自定义的转换器类,注册到系统默认的转换器字典中
app.url_map.converters["mob"] = MobileConverter
"""
DEFAULT_CONVERTERS = {
"default": UnicodeConverter,
"string": UnicodeConverter,
"any": AnyConverter,
"path": PathConverter,
"int": IntegerConverter,
"float": FloatConverter,
"uuid": UUIDConverter,
"mob": MobileConverter
}
"""
@app.route('/mobile/<mob:mobile_number>')
def hello_world(mobile_number):
print(mobile_number)
print(type(mobile_number))
return 'Hello World!'
4.请求
@app.route('/index', methods=["post", "get"])
def index():
# =======request基本属性========
http://127.0.0.1:8000/index
访问的url地址
print(request.url)
远程的ip和用户
print(request.remote_addr)
print(request.remote_user)
请求头--字典
print(request.headers)
print(request.headers["Host"])
print(request.headers.get("Host", "默认值"))
请求方式 返回的请求方式的大写字符串
print(request.method)
if request.method == "GET"
=======request参数属性========
1.通过请求路径携带参数: <转换器名称:变量名>
2.查询字符串参数: user?name=curry&age=18 [GET请求]
request.args
print(request.args.get("name"))
print(request.args.get("age"))
3.表单参数:{
"name": "james", "age":38} [POST请求]
request.form
print(request.form.get("name"))
print(request.form.get("age"))
4.json字符串参数 '{"name": "kobe", "age":42}' [POST请求]
request.json ==> 将json字符串转换成字典
print(request.json.get("name"))
print(request.json.get("age"))
5.文件类型参数 {
"img": 图片数据}
request.files
# type:FileStorage 类型声明
file_img = request.files["img"] # type:FileStorage
# 保存图片--七牛云存储图片数据
file_img.save('./1.png')
return 'index page'
5.响应
import json
from flask import Flask, render_template, make_response, Response, Request, jsonify, redirect
# static_folder 静态文件夹的名称 默认值:static
# template_folder 模板文件夹的名称 默认值:templates
# static_url_path 静态资源的url访问前缀 默认值: /static
# 访问静态url: 127.0.0.1:8000/static/img/kobe.png
# __name__
app = Flask(__name__)
# flask中不允许中文转化成ASCII编码
app.config["JSON_AS_ASCII"] = False
# 访问静态url: 127.0.0.1:8000/resource/img/kobe.png
# app = Flask(__name__, static_folder="static", static_url_path="/resource")
# 需求:返回静态资源作为响应 [flask内部已经实现了返回静态文件的视图函数static] [了解]
@app.route('/demo1')
def demo1():
return 'Hello World!'
"""
Map([<Rule '/demo1' (OPTIONS, GET, HEAD) -> demo1>,
访问静态资源的路径
<Rule '/static/<filename>' (OPTIONS, GET, HEAD) -> static>])
"""
# 需求:返回模板文件作为响应[了解]
@app.route('/demo2')
def demo2():
return render_template("index.html")
# 需求:返回响应元组(响应体, 响应状态码, 响应头)
@app.route('/demo3')
def demo3():
return "我是响应体内容", 666, {
"python": "itcast"}
# 需求:返回响应对象,自定义状态码 响应头 [重点 推荐]
@app.route('/demo4')
def demo4():
# 1.创建响应对象
response = make_response("我是真的响应体信息") # type:Response
# 2.设置状态码
response.status_code = 201
# 3.设置响应头
response.headers["token"] = "abc"
# response.set_cookie()
return response
# 需求:返回json字符串作为响应 【重点】
@app.route('/demo5')
def demo5():
# 1.准备字典
user_dict = {
"name": "科比",
"number": 24
}
# 方法1 json.dumps()
# ensure_ascii=False 不允许中文转换成ASCII编码
# user_json = json.dumps(user_dict, ensure_ascii=False)
# response.headers["Content-Type"] = "application/json"
# return user_json
# 方法2:jsonify() 【推荐】
# 1.将字典转换成json字符串,并且包装成response对象
# 2.在响应头中设置了Content-Type="application/json"
json_response = jsonify(user_dict)
return json_response
# 需求:重定向到黑马官网 http://www.itheima.com
@app.route('/demo6')
def demo6():
url = 'http://www.itheima.com'
# 重定向到自身视图函数
# redirect('/demo5')
return redirect(url)
6.三种状态保持
“cookie”
@app.route('/login')
def login():
"""
登录成功,往响应对象中添加cookie信息
:return:
"""
# 1.构建响应对象
response = make_response("login success") # type:Response
# 2.往响应对象中添加cookie字典
# 参数1:key
# 参数2:value
# max_age=3600 过期时长 单位s
response.set_cookie("name", "laowang", max_age=3600)
# 本质是让max_age=0
# response.delete_cookie("name")
# 3.返回响应
return response
@app.route("/index")
def index():
"""
利用请求对象提取cookie信息
:return:
"""
# 提取cookie字典
name = request.cookies.get("name")
return "index : {}".format(name)
session
app.secret_key = "python38"
# app.config["SECRET_KEY"] = "xxx"
# 设置session有效时长 1天
app.permanent_session_lifetime = timedelta(days=1)
"""
session 本质就是一个字典,能够存储键值对信息
注意:使用flask中session需要设置加密字符串secret_key
"""
@app.route('/login')
def login():
# 在session保存用户字典信息
session["name"] = 'harden'
# 开启有效时长的属性
session.permanent = True
return 'login success'
@app.route('/index')
def index():
# 提取session中用户信息
name = session.get("name")
print(name)
return "index page : {}".format(name)
jwt_oken
# 需求:登录成功颁发2小时有效的token
# 特点:不能保证信息加密,只能保证传输过程中未篡改token信息
# JWE
@app.route('/login')
def login():
# 格林威治0时区的当前时间 + 2小时时间戳
expire = datetime.utcnow() + timedelta(hours=2)
# 1.构建载荷信息[dict]
user_dict = {
"user_id": 66,
"user_name": "xiaoming",
"exp": expire
}
# 2.构建秘钥
key = "python38"
# 3.生成2小时有效的token
token = jwt.encode(payload=user_dict, key=key, algorithm="HS256")
token = token.decode()
return 'success: {}'.format(token)
@app.route('/profile')
def profile():
"""
获取前端请求的token,验证token,提取载荷信息
:return:
"""
# 1.提取请求头中的token字符串
token = request.headers.get("Authorization")
# 2.校验token,提取载荷信息
try:
payload = jwt.decode(token, key="python38", algorithm=["HS256"])
except Exception as e:
print(e)
payload = None
if payload:
# 3.提取载荷中用户信息
user_name = payload.get("user_name")
user_id = payload.get("user_id")
return "porfile index: user_name: {} user_id: {}".format(user_name, user_id)
else:
return "invalid token", 401
7.异常处理
@app.route('/')
def hello_world():
a = 1 / 0
# 参数:只能是http标准错误状态码
abort(404) # 资源找不到
"""
abort(404) # 资源找不到
abort(405) # 请求方式错误
abort(401) # 权限认证失败
abort(403) # 权限认证成功,限制访问
abort(500) # 服务器代码错误
"""
return 'Hello World!'
# 需求:捕获项目中所有的404异常,统一到统一的页面
# 参数: code_or_exception 捕获错误状态码或者异常类
# 注意:接受异常字符串
@app.errorhandler(404)
def error_404_headler(e):
print(e)
return redirect("http://err.www.mi.com/04.html")
@app.errorhandler(ZeroDivisionError)
def ZeroDivisionError(_):
# _ 忽略参数
return "不能除0"