Flask基础
Flask是一个Python编写的Web微框架,让我们可以使用Python语言快速实现一个网站或Web服务
# 安装flask
pip install flask
1.flask对象
创建flask_demo01_hello_world.py
# 1. 从 flask 模块导入 Flask 类
from flask import Flask
# 2.创建 flask 对象
# 参数1:__name__,如果从当前文件启动,那么值是__main__,如果是从其他模块调用运行的那么值是模块的名字
# 参数2:static_url_path,表示静态资源【CSS、Img……】的访问地址,/static
# 参数3:static_folder,用于存储静态资源的文件夹,默认文件名为:static
# 参数4:template_folder,模板文件夹,特指html文件,默认文件名为:templates
app = Flask(__name__)
# 使用app,通过路由绑定一个视图函数
# 注意:视图函数必须有返回值
@app.route("/")
def helloworld():
return "hello world Flask"
# 判断是否直接使用当前模块运行程序
# 如果 __name__ == "__main__" 那么运行当前程序
if __name__ == "__main__":
# 运行当前程序,http://127.0.0.1:5000
app.run(debug=True)
# app.run() 参数
# 参数1:host,默认 127.0.0.1
# 参数2:post,默认 5000
# 参数3:debug,默认 False
2.URL路由选择器
创建flask_demo02_url_map.py
"""
查看哪些路由(地址)可以访问
- 格式:使用 app.url_map,返回的是 app 装饰的所有路由和路径之间的关系
- 注意点:只有被 app.url_map 包含进来的路由(地址)才能被访问
"""
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "this is index"
@app.route("/home")
def home():
return "this is home"
if __name__ == "__main__":
print(app.url_map)
app.run(debug=True)
创建flask_demo03_dynamic_params.py
"""
在访问路由的时候指定参数【动态参数】
- 格式:@app.route("/<类型:变量名>")
- 常见参数类型(默认 path)
- 整数:int
- 小数:float
- 字符串:path
"""
from flask import Flask
app = Flask(__name__)
# 接收一个整数
@app.route("/<int:number>")
def get_intNumber(number):
return f"the int is {number}"
# 接收一个小数
@app.route("/<float:number>")
def get_floatNumber(number):
return f"the float is {number}"
# 接收一个字符串
@app.route("/<path:number>")
def get_pathNumber(number):
return f"the path is {number}"
if __name__ == "__main__":
app.run(debug=True)
创建flask_demo04_custom_converter.py
"""
自定义参数类型(自定义转换器)
- 背景:
- 如果系统提供的 int,float 等参数类型满足不了需求的时候,我们需要自定义
- 之所以 int,float,path 可以接收不同的数据类型,是因为,系统已经提供好对应的转换器了
- 自定义转换器格式
- 1. 定义类,继承自 BaseConverter
- 2. 重写 init 方法
- 3. 初始化父类成员变量,还有子类自己的规则
- 4. 将转换器类添加到系统默认的转换器列表中
需求:接收三位整数
"""
import typing as t
from flask import Flask
from werkzeug.routing import BaseConverter
from werkzeug.routing.map import Map
app = Flask(__name__)
# - 1. 定义类,继承自 BaseConverter
class MyRegexConverter(BaseConverter):
# 接收三位整数
# regex = "\d{3}" # 直接指定规则不灵活,具体匹配什么规则应该交给路由
# - 2. 重写 init 方法
# 接收两个参数:map 和 regex
def __init__(self, map, regex) -> None:
# - 3. 初始化父类成员变量,还有子类自己的规则
super(MyRegexConverter, self).__init__(map)
self.regex = regex
# - 4. 将转换器类添加到系统默认的转换器列表中
app.url_map.converters["threeDigit"] = MyRegexConverter
# 匹配三位整数
@app.route("/<threeDigit('\d{3}'):number>")
def get_threeNumber(number):
return f"the threeNumber is {number}"
# 匹配四位整数
@app.route("/<threeDigit('\d{4}'):number>")
def get_fourNumber(number):
return f"the fourNumber is {number}"
# 匹配一个手机号
@app.route("/<threeDigit('^1[3-9]\d{9}'):number>")
def get_phoneNumber(number):
return f"the phoneNumber is {number}"
if __name__ == "__main__":
app.run(debug=True)
创建flask_demo05_methods.py
"""
给路由增加其他的访问方式
- 格式:@app.route('路径', methods=['请求方式1', '请求方式2', ...])
- 常见的请求方式:
- GET,POST,PUT,DELETE
- 注意:如果不指定请求方式,默认支持 GET 请求
- 发送 POST 请求:
- 1. 写一个表单
- 2. 发送一个 ajax 请求
- 3. 使用 postman 发送 post 请求
"""
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=["POST", "GET"])
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)
3.返回值
创建flask_demo06_return_response.py
"""
返回响应(字符串)
- 1. 直接返回响应体数据
- return '字符串'
- 2. 直接返回响应体数据+状态码
- return '字符串', 状态码
- 3. 直接返回响应体数据+状态码+响应头信息
- return '字符串', 状态码, {'key', 'value'}
"""
from flask import Flask
app = Flask(__name__)
@app.route("/")
def helloworld():
# - 1. 直接返回响应体数据
# return "hello world Flask"
# - 2. 直接返回响应体数据+状态码
# return "hello world Flask", 666
# return "hello world Flask", "666 BIGERROR"
# - 3. 直接返回响应体数据+状态码+响应头信息
return (
"hello world Flask",
200,
{"Content-Type": "application/json", "name": "wang"},
)
if __name__ == "__main__":
app.run(debug=True)
创建flask_demo07_jsonify.py
"""
通过 jsonify 返回json数据
- 格式:jsonify(dict)
- 简化格式:jsonify(key1=value1, key2=value2)
"""
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def helloworld():
# 1. 定义字典
dict = {"name": "wang", "age": 23}
# 2. 返回json数据
# return jsonify(dict)
# 3. 返回json数据简化格式
return jsonify(name="zhao", age=22)
if __name__ == "__main__":
app.run(debug=True)
4.重定向
创建flask_demo08_redirect.py
"""
重定向
- 格式:redirect('地址'),地址既可以是本地服务器的地址,也可以是其他服务器地址
- 注意点:重定向的代号是302
- 特点:重定向是两次请求
"""
from flask import Flask, redirect
app = Flask(__name__)
@app.route("/")
def helloworld():
return redirect("/index")
@app.route("/index")
def index():
return "this is index"
if __name__ == "__main__":
app.run(debug=True)
创建flask_demo09_redirect_practice.py
"""
重定向
- 格式:redirect('地址'),地址既可以是本地服务器的地址,也可以是其他服务器地址
- 注意点:重定向的代号是302
- 特点:重定向是两次请求
"""
from flask import Flask, redirect
app = Flask(__name__)
@app.route("/")
def helloworld():
return redirect("/taobao")
@app.route("/taobao")
def taobao():
# 重定向到淘宝网
return redirect("https://www.taobao.com/")
@app.route("/index")
def index():
return "this is index"
if __name__ == "__main__":
app.run(debug=True)
5.反向解析
创建flask_demo10_url_for.py
"""
url_for
- 解释:称为反解析,返回的是视图函数对应的路由地址
- 格式:url_for('视图函数', key=value)
- 注意:url_for 经常和redirect配合使用,传递参数
- 例如:response = redirect(url_for("taobao", token=123))
"""
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route("/")
def helloworld():
return "hello world Flask"
@app.route("/jingdong")
def jingdong():
# 1. 通过 url_for 找到taobao的地址,然后通过redirect进行重定向
response = redirect(url_for("taobao", token=123))
# 2. 返回响应体对象
return response
@app.route("/pinduoduo")
def pinduoduo():
response = redirect(url_for("taobao", token=456))
return response
@app.route("/taobao/<int:token>")
def taobao(token):
if token == 123:
return "欢迎京东用户!"
elif token == 456:
return "欢迎拼多多的用户!"
else:
return "欢迎其他用户!"
if __name__ == "__main__":
app.run(debug=True)
创建flask_demo11_abort_errorhandler.py
"""
abort & errorhandler
- 使用场景:当访问服务器资源的时候,如果找不到该资源可以报出异常信息,使用errorhandler捕捉
- 格式:abort(代号)
- 格式:@app.errorhandler(代号)
"""
from flask import Flask, abort
app = Flask(__name__)
@app.route("/")
def helloworld():
abort(403)
return "hello world Flask"
@app.errorhandler(404)
def page_not_found(e):
return "页面找不到"
@app.errorhandler(403)
def Forbidden(e):
return "禁止访问"
if __name__ == "__main__":
app.run(debug=True)
6.request
创建flask_demo12_request.py
"""
request 对象参数
- request.data: 获取非表单(ajax)以post提交的数据
- request.form: 获取表单以post提交的数据
- request.args: 获取问号后面的查询参数
- request.method: 获取的请求方式
- request.url: 获取请求的地址
- request.files: 获取input标签中type类型为file的文件
"""
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def helloworld():
print(request.method)
print(request.url)
print(request.args)
# print(request.args['name']) # 字典不建议使用 [] 的方式进行取值,极易报错
print(request.args.get("name")) # 字典推荐使用 .get() 的方式取值
print(request.args.get("age", 23))
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)
7.加载参数
创建flask_demo13_load_appParams.py
"""
加载 app 程序运行参数
- 1. 从配置类(对象)中加载
- app.config.from_object(obj)
- 2. 从配置文件中加载
- app.config.from_pyfile(file)
- 3. 从环境变量中加载【了解即可】
- app.config.from_envvar(环境变量)
- app.config: 表示 app 程序,运行所有的参数信息
"""
from flask import Flask
app = Flask(__name__)
# # 1. 从配置类(对象)中加载
# class MyConfig(object):
# # 调试模式
# DEBUG = True
# app.config.from_object(MyConfig)
# 2. 从配置文件中加载
app.config.from_pyfile("Config.ini")
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
app.run()
创建Config.ini
DEBUG = True
8.请求钩子
创建flask_demo14_request_hook.py
"""
请求钩子
- 解释:当访问正常视图函数的时候,顺带执行的方法
- 常见的请求钩子有四种:
- 1. before_first_request:在处理第一个请求前执行【已不使用】
- 2. before_request:在每次请求前执行,在该装饰函数中,一旦return,视图函数不再执行
- 3. after_request:如果没有抛出错误,在每次请求后执行
接收一个参数:视图函数作出的响应
在此函数中可以对响应值,在返回之前做最后一步处理,再返回
- 4. teardown_request:再每次请求后执行
接收一个参数:用来接收错误信息
- 顺序:
1. before_request
2. after_request
3. teardown_request
"""
from flask import Flask
app = Flask(__name__)
# 在flask2.3版本之后,该装饰器的功能在创建应用时运行,无需手动添加该装饰器
# @app.before_first_request
# def before_first_request():
# print("before_first_request")
# 每次请求前都执行,适合对请求参数做校验,访问统计
@app.before_request
def before_request():
print("before_request")
# 视图函数执行之后,返回该方法,适合对返回值做统一处理
@app.after_request
def after_request(resp):
print("after_request")
resp.headers["Content-Type"] = "application/json"
return resp
# 请求销毁之后执行
@app.teardown_request
def teardown_request(e):
print("teardown_request")
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)