趁着这假期的时间,把这flask回顾回顾,
一、Hello Flask
#1.从flask模块导入了Flask类
from flask import Flask
#2.创建flask对象
#参数1: __name__,如果从当前文件启动,那么值是__main__,如果是从其他模块调用运行的那么值是模块的名字
#参数2: static_url_path,表示静态资源的访问地址,/static
#参数3: static_folder,用来存储静态资源的,默认名字是static
#参数4: template_folder,模板文件夹,默认的值是templates
app = Flask(__name__)
print(__name__)
print(app.static_url_path)
print(app.static_folder)
print(app.template_folder)
#使用app,通过路由绑定一个视图函数
#注意点: 视图函数一定要有返回值
@app.route('/')
def hello_world():
return "hello world Flask"
#判断是否直接使用当前模块运行程序
if __name__ == '__main__':
#运行app程序
app.run()
二、url_map
查看哪些路由(地址)可以访问
格式: 使用app.url_map,返回的是app装饰的所有的路由和路径之间的映射关系
注意: 只有被app.url_map包含进来的路由(地址)才能被访问
from flask import Flask
app = Flask(__name__)
@app.route('/index')
def index():
return "this is index"
@app.route("/index2")
def index2():
return "this is index2"
print(app.url_map)
if __name__ == '__main__':
app.run()
# Map([<Rule '/index2' (GET,OPTIONS,HEAD) -> index2>,# <Rule '/index' (GET,HEAD) -> index>,# <Rule '/static/<filename>' (GET,HEAD) -> static>])
三、app.run()
- 参数1: host,如果我们不指定,默认值是127.0.0.1
- 参数2: port,默认的值是5000
- 参数3: debug,调试模式,如果不指定,默认的值是False
如果参数3写了没有生效的话,直接在Pycharm中设置就行
from flask import Flask
app = Flask(__name__)
@app.route('/haha')
def hello_world():
#print(1/0)
return "<h1>helloworld</h1>"
if __name__ == '__main__':
app.run(host="127.0.0.1",port=5001,debug=True)
四、指定参数
在访问路由的时候指定参数
- 格式: @app.route("/<类型:变量名>")
- 常见的参数类型
- 整数 int
- 小数 float
- 字符串 path(默认就是path)
from flask import Flask
app = Flask(__name__)
#接收一个整数
@app.route('/<int:number>')
def get_intnumber(number):
return "the int is %s"%number
#接收一个小数
@app.route('/<float:number>')
def get_floatnumber(number):
return "the float is %s"%number
#接收一个字符串
@app.route('/<path:number>')
def get_pathnumber(number):
return "the path is %s"%number
if __name__ == '__main__':
app.run(debug=True)
五、自定义转换器
背景:
-
如果系统提供的int,float,等参数类型满足不了需求的时候,我们需要自定义
-
之所以,int,path可以接收不同的数据类型,是因为,系统已经提供好对应的转换器了
-
自定义转换器格式
需求: 接收三位整数
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# - 1.定义类,继承自BaseConverter
class MyRegexConverter(BaseConverter):
#这样直接指定规则,不够灵活,具体应该匹配什么规则应该交给路由
# regex = "\d{3}"
# - 2.重写init方法,接收两个参数
def __init__(self,map,regex):
# - 3.初始化父类成员变量,还有子类自己的规则
super(MyRegexConverter,self).__init__(map)
self.regex = regex
# - 4.将转换器类,添加到系统默认的转换器列表中
app.url_map.converters["re"] = MyRegexConverter
#打印输出所有的系统转换器列表
print(app.url_map.converters)
#匹配三位整数
#使用re('规则'),实际上是传递了两个参数,参数1: app.url_map,参数2:括号中写的正则规则
@app.route('/<re("\d{3}"):number>')
def hello_world(number):
return "the three number is %s"%number
#匹配四位整数
@app.route('/<re("\d{4}"):number>')
def get_four_number(number):
return "the four number is %s"%number
#匹配一个手机号
@app.route('/<re("1[3-9]\d{9}"):phone>')
def get_phone_number(phone):
return "the phone number is %s"%phone
if __name__ == '__main__':
app.run(debug=True)
六、增加请求方式
格式: @app.route('路径',methods=['请求方式1','请求方式2',....])
- 常见的请求方式:
- GET,POST,PUT,DELETE
from flask import Flask
app = Flask(__name__)
@app.route('/',methods=["POST","GET"])
def hello_world():
return "helloworld"
if __name__ == '__main__':
print(app.url_map)
app.run(debug=True)
七、返回响应(字符串)
- 直接返回响应体数据
- return '字符串'
- 直接返回响应体数据+状态码
- return '字符串',转台码
- 直接返回响应体数据+状态码+响应头信息
- return '字符串',转台码,{'key':'value'}
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
# - 1.直接返回响应体数据
# return 'helloworld'
# - 2.直接返回响应体数据+状态码
# return 'helloworld',666
# return 'helloworld',"666 BIGERROR"
# - 3.直接返回响应体数据+状态码+响应头信息
return 'helloworld',200,{"Content-Type": "application/json","name": "pony"}
if __name__ == '__main__':
app.run(debug=True)
八、返回json数据
- 格式: jsonify(dict)
- 简化格式: jsonify(key=value,key2=value2)
from flask import Flask,jsonify
app = Flask(__name__)
@app.route('/')
def hello_world():
#1.定义字典
dict = {
"name":"banzhang","age":29
}
#2.返回json数据
# return jsonify(dict)
#3.返回json数据简化格式
return jsonify(name="pony",age=20)
if __name__ == '__main__':
app.run(debug=True)
九、重定向
from flask import Flask,jsonify,redirect
app = Flask(__name__)
@app.route('/index')
def index():
return redirect("/index2")
@app.route('/index2')
def index2():
return "我是index2页面"
if __name__ == '__main__':
app.run()
from flask import Flask,redirect
app = Flask(__name__)
@app.route('/jingdong')
def jingdong():
#跳转到淘宝去
return redirect("http://www.taobao.com")
if __name__ == '__main__':
app.run(debug=True)
十、url_for
from flask import Flask,url_for,redirect
app = Flask(__name__)
@app.route('/jingdong')
def jingdong():
print(url_for("taobao",token=123))
#1.通过url_for找到taobao的地址,然后通过redirect,进行重定向
response = redirect(url_for("taobao",token=123))
#2.返回响应体对象
return response
@app.route('/yamaxun')
def yamaxun():
#1.通过url_for找到taobao的地址,token=456))
#2.返回响应体对象
return response
@app.route('/taobao/<int:token>')
def taobao(token):
if token == 123:
return "欢迎京东用户,给你打5折"
elif token == 456:
return "欢迎亚马逊用户,给你打9折"
else:
return "欢迎其他网站用户,给你9.9折"
if __name__ == '__main__':
app.run(debug=True)
十一、abort&errorhandler,异常处理
- 使用场景: 当访问服务器资源的时候,如果找不到该资源,可以报出异常信息,使用errorhandler捕捉
- 格式: abort(代号)
- 格式: @app.errorhandler(代号)
abort,异常抛出,主动抛出异常的状态码
errorhandler,异常捕获,用来监听捕获异常并返回自定义的页面处理
from flask import Flask,abort
app = Flask(__name__)
@app.route('/')
def hello_world():
abort(403)
return "helloworld"
#只要出现了404异常,就能捕捉
@app.errorhandler(404)
def page_not_found(e):
print(e)
return "<h1 style='color:red'>页面找不到</h1>"
#只要出现了403异常,就能捕捉
@app.errorhandler(403)
def forrden(e):
print(e)
return "<h1 style='color:red'>禁止访问</h1>"
if __name__ == '__main__':
app.run(debug=True)
或者可以这样写
from flask import Flask,request,abort,Response
app = Flask(__name__)
@app.route("/login",methods=["GET"])
def login():
name = ""
pwd = ""
if name != "zhangsan" or pwd != "admin":
"""
使用abort函数可以立即终止视图函数的执行
并可以返回给前端特定的信息
1. 传递状态码信息,必须是标准的http状态码
可以接受状态码信息,返回给前端已经默认好的信息
"""
abort(404)
"""
2. 传递响应体的信息,Response()里面的内容会在前端上显示出来
resp = Response("login Failed")
abort(resp)
"""
return "login success"
"""自定义异常处理"""
@app.errorhandler(404)
def handle_404_error(error): # 接受一个错误信息
"""自定义的处理404错误方法"""
'''这个函数的返回值会是前端所看到的最终的结果'''
return "出现了404错误,错误信息:%s"%error
if __name__ == '__main__':
app.run(debug=True)
十二、 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 hello_world():
print(request.method)
print(request.url)
print(request.args)
# print(request.args["name"]) #字典不建议使用[]的方式取值
print(request.args.get("name")) #如果获取不到不会报错,返回None
print(request.args.get("age",39)) #如果获取不到,设置一个默认值
return "helloworld"
if __name__ == '__main__':
app.run(debug=True)
十三、加载app程序运行参数
- 从配置类(对象)中加载
- app.config.from_object(obj)
- 从配置文件中加载
- app.config.from_pyfile(file)
- 从环境变量中加载(了解)
- app.config.from_envvar(环境变量)
- app.config: 表示app程序,运行所有的参数信息
from flask import Flask
app = Flask(__name__)
# print(app.config)
# 1.从配置类(对象)中加载
class MyConfig(object):
#调试模式
DEBUG = True
#MysqL数据库配置
#redis配置
#session配置
# app.config.from_object(MyConfig)
# 2.从配置文件中加载,此时目录下创建一个COnfig.ini的文件
# app.config.from_pyfile("Config.ini")
# 3.从环境变量中加载
app.config.from_envvar("FLASKING")
@app.route('/')
def hello_world():
return "helloworld"
if __name__ == '__main__':
app.run()
十四、请求钩子
在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:
- 在请求开始时,建立数据库连接;
- 在请求开始时,根据需求进行权限校验;
- 在请求结束时,指定数据的交互格式;
为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子
常见的请求钩子有四种:
- before_first_request:在处理第一个请求前执行
- before_request:在每次请求前执行,在该装饰函数中,一旦return,视图函数不再执行
- after_request:如果没有抛出错误,在每次请求后执行
- teardown_request:在每次请求后执行,接受一个参数:用来接收错误信息
from flask import Flask
app = Flask(__name__)
#before_first_request装饰的函数在第一次访问的时候执行,里面适合做初始化操作,比如,io文件读写
@app.before_first_request
def before_first_request():
print("before_first_request")
#before_request,每次请求前都执行,适合对请求参数做校验,访问统计
@app.before_request
def before_request():
print("before_request")
#after_request,视图函数执行之后,返回该方法,适合对返回值做统一处理,比如:返回统一的json数据格式
@app.after_request
def after_request(resp):
print("after_request")
resp.headers["Content-Type"] = "application/json"
return resp
#teardown_request,请求销毁之后,执行该方法,适合做异常信息统计
@app.teardown_request
def teardown_request(e):
print(e)
print("teardown_request")
@app.route('/')
def hello_world():
return "helloworld"
@app.route('/index')
def index():
return "index"
if __name__ == '__main__':
app.run(debug=True)
# 第一次请求
# before_first_request
# before_request
# after_request
# teardown_request
# 第二次请求
# before_request
# after_request
# teardown_request