Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言编写的 **轻量级Web开发框架** ,其本身相当于一个内核,主要实现路**由分发和模板渲染功能**。
Flask中常用的扩展包:
mkvirtualenv flask_env -p python3 #创建名为flask_env的虚拟环境,使用python3解释器
pip install flask==1.0.3 #安装版本为1.0.3的flask包
from flask import Flask # 导入flask包
app = Flask(__name__) #创建flask对象,接收一个参数__name__,它会指向程序所在的包
@app.route('/') #定义路由
def index(): #视图
return 'hello flask'
if __name__=='__main__':
app.run() #运行程序
# app.run()中可以添加参数
# host: 绑定的ip(域名) 0.0.0.0
# port: 监听的端口号
# debug: 是否开启调试模式 1> 可以在网页上显示python错误 2> 更新代码后测试服务器自动重启
#app.run(host='0.0.0.0', port=8000, debug=True)
运行结果:
/home/ubuntu/.virtualenvs/flask_env/bin/python /home/ubuntu/PycharmProjects/flask2/helloflask.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Serving Flask app "helloflask" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
export FLASK_APP=xx.py #指定flask应用所在的文件路径
export FLASK_ENV=development #设置项目的环境,默认是生产环境
flask run -h 0.0.0.0 -p 8000 #启动测试服务器并接收请求
# 获取环境变量
export # 查看所有环境变量
echo $环境变量 # 查看指定的环境变量
# 设置环境变量
export 环境变量名=值 # 给本次会话设置环境变量, 一旦终端关闭, 环境变量会清空
# 将环境变量写入配置文件(.bashrc/.bash_profile), 重新打开终端时再次加载环境变量
from flask import Flask
app=Flask(__name__)
@app.route('/hello',methods=['get','post'])
def index():
return 'index'
if __name__=='__main__':
print(app.url_map)
# 获取路由信息
print('-----------------------------------')
for rule in app.url_map.iter_rules():
print(rule.rule, rule.methods, rule.endpoint)
# 具体的获取每条路由信息中的项
app.run(debug=True)
运行结果:
Map([<Rule '/hello' (POST, OPTIONS, GET, HEAD) -> index>,
<Rule '/static/' (OPTIONS, GET, HEAD) -> static>])
-----------------------------------
/hello {
'POST', 'OPTIONS', 'GET', 'HEAD'} index
/static/<path:filename> {
'OPTIONS', 'GET', 'HEAD'} static
from flask import Flask
app=Flask(__name__)
@app.route('/user/' )
def index(userid):
print(userid)
return 'index'
if __name__=='__main__':
app.run(debug=True)
使用postment发送get请求:http://127.0.0.1:5000/user/18240118472
运行结果:
18240118472
127.0.0.1 - - [17/Mar/2020 19:49:30] "GET /user/18240118472 HTTP/1.1" 200 -
from flask import Flask
app = Flask(__name__)
@app.route('/user/' )
def index(userid):
print(userid)
return 'index'
if __name__=='__main__':
app.run()
使用postment分别发送get请求:http://127.0.0.1:5000/user/18240
http://127.0.0.1:5000/user/18240a
运行结果分别为:
18240
127.0.0.1 - - [17/Mar/2020 20:03:42] "GET /user/18240 HTTP/1.1" 200 -
127.0.0.1 - - [17/Mar/2020 20:05:00] "GET /user/18240a HTTP/1.1" 404 -
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
class CustomConverter(BaseConverter):
regex = '\w{3}' # 3个字符
app.url_map.converters['abc']=CustomConverter
@app.route('/user/' )
def index(mobile):
print(mobile)
return 'index'
if __name__=='__main__':
print(app.url_map.converters) #打印所有路由转换器
print('------------------')
app.run()
使用postment分别发送get请求:http://127.0.0.1:5000/user/zhu
运行结果:
lt': werkzeug.routing.UnicodeConverter'>, 'string': werkzeug.routing.UnicodeConverter'>, 'any': werkzeug.routing.AnyConverter'>, 'path': werkzeug.routing.PathConverter'>, 'int': werkzeug.routing.IntegerConverter'>, 'float': werkzeug.routing.FloatConverter'>, 'uuid': werkzeug.routing.UUIDConverter'>, 'abc': __main__.CustomConverter'>}
------------------
zhu
127.0.0.1 - - [17/Mar/2020 20:24:04] "GET /user/zhu HTTP/1.1" 200 -
属性 | 说明 | 类型 |
---|---|---|
url | 记录请求的URL地址 | str |
method | 记录请求使用的HTTP方法 | str |
headers | 记录请求中的报文头 | EnvironHeaders 类字典对象 |
args | 记录请求中的查询参数 | MultiDict |
form | 记录请求中的表单数据 | MultiDict |
data | 记录请求的数据,并转换为字符串 | bytes |
json | 记录请求体中的json数据 | Dict |
files | 记录请求上传的文件 | MultiDict[str: FileStorage] |
from flask import Flask, request
# from werkzeug.datastructures import FileStorage
app = Flask(__name__)
@app.route('/', methods=['get', 'post'])
def index():
# 获取请求的基础数据
# print(request.url) # 请求的URL
# print(request.method) # 本次请求的请求方式
# print(request.headers) # 获取请求头信息 类字典对象
# print(request.headers['Host'])
# print(request.headers.get('Host')) # 建议使用get方法, 键不存在不报错
# 请求传递数据 1> URL路径 -> 路由变量 2> 查询字符串 get 3> 请求体 post 4> 请求头 -> request.headers
# 获取查询字符串 -> request.args xx?name=zs&age=20 类字典对象
# print(request.args.get('name'))
# print(request.args.get('age'))
# 请求体: 键值对(表单) 文本(json/xml) 文件(图片/音频)
# 获取post键值对 -> request.form 类字典对象
# print(request.form.get('username'))
# 获取post文本数据 -> request.data / request.json
# print(request.data) # 返回bytes类型
# print(request.json.get('age')) # request.json直接将json字符串转为字典
# 获取post文件 -> request.files 类字典对象
file = request.files.get("avatar") # type: FileStorage
# print(type(file)) # 返回 FileStorage文件对象
# 将文件保存到本地
file.save('4323.jpg')
# 获取文件的二进制数据
# img_bytes = file.read()
# print(img_bytes)
return "index"
if __name__ == '__main__':
app.run(debug=True)
使用postman发送请求:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovrKPdNn-1586763119996)(http://my-picture-1258042328.cos.ap-shanghai.myqcloud.com/flask%E5%9F%BA%E7%A1%80/20200317090928173.png)]
运行结果:
项目中会新出现一个4323.jpg文件
127.0.0.1 - - [17/Mar/2020 21:05:48] "GET / HTTP/1.1" 200 -
from flask import Flask
app = Flask(__name__, # 导入名称, flask会根据该参数查询静态文件的存储路径
# 官方建议直接使用__name__, 表示从当前目录中查询静态文件存储路径
static_folder="static1", # 设置静态文件的存储目录
static_url_path='/res/img', # 设置静态文件的URL访问路径 如 127.0.0.1:5000/res/img/123.jpg
)
if __name__ == '__main__':
app.run(debug=True)
from flask import Flask, make_response, Response
app= Flask(__name__)
@app.route('/demo')
def demo():
response = make_response('hello')
response.header['A']=10
return response
if __name__ == '__main__':
app.run()
from flask import Flask, make_response, Response,jsonify
# import json
app = Flask(__name__)
@app.route('demo')
def demo():
dict_={
'name':'zhu','age':24}
return jsonify(dict_)
# return json.dumps(dict_)
if __name__=='__main__':
app.run()
from flask import Flask,redirect,url_for
app=Flask(__name__)
@app.route('/demo1')
def demo1():
url_=url_for('demo2',userid=1)
return redirect(url_)
@app.route('/demo2/' )
def demo2(userid):
print(userid)
return 'demo2'
if __name__ == '__main__':
app.run()
运行结果:
127.0.0.1 - - [17/Mar/2020 22:40:22] "GET /demo1 HTTP/1.1" 302 -
127.0.0.1 - - [17/Mar/2020 22:40:22] "GET /demo2/1 HTTP/1.1" 200 -
1
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/demo5')
def demo5():
# 可以通过第二个返回值 来设置自定义的响应状态码 实现自定义的交互规则 700 密码错误 701 用户不存在
# 返回值: 响应体, 响应状态码, 响应头
return 'demo5', 700, {
'B': 40}
if __name__ == '__main__':
app.run(debug=True)
运行结果:
127.0.0.1 - - [17/Mar/2020 22:44:25] "GET /demo HTTP/1.1" 700 -
from flask import Flask ,make_response, Response, request
app =Flask(__name__)
@app.route('/demo1')
def demo1():
response= make_response()
response.set_cookie('name','zhu',max_age=600)
return response
@app.route('/demo2')
def demo2():
print(request.cookies.get('name'))
return 'demo2'
if __name__=="__main__":
app.run()
运行结果:
127.0.0.1 - - [17/Mar/2020 22:59:31] "GET /demo1 HTTP/1.1" 200 -
127.0.0.1 - - [17/Mar/2020 22:59:35] "GET /demo2 HTTP/1.1" 200 -
zhu
from flask import Flask session
from datetime import timedelta
app=Flask(__name__)
app.secret_key ='test'
app.permanent_session_lifetime = timedelta(days=7)
@app.route('/demo1')
def demo1():
session['password']= '123'
session.permanent=True
return 'demo1'
@app.route('/demo2')
def demo2():
print(session.get('password'))
return 'demo2'
if __name__=='__main__':
app.run()
运行结果:
127.0.0.1 - - [17/Mar/2020 23:16:44] "GET /demo1 HTTP/1.1" 200 -
123
127.0.0.1 - - [17/Mar/2020 23:17:11] "GET /demo2 HTTP/1.1" 200 -
from flask import Flask ,abort
app = Flask(__name__)
@app.errorhandler(404)
def error_404(error):
return "您访问的页面去浪迹天涯了
%s" % error
@app.errorhandler(ZeroDivisionError)
def error_zero(error):
return '除数不能为0'
@app.route('/') #访问其他路由时会捕获404异常,跳到error_404函数
def index():
a=1/0 #产生除数为0的异常,会主动跳到error_zero函数
#abort(500) abort()函数可以主动抛出异常
return 'index'
if __name__=='__main__':
app.run()
from flask import Flask ,Response
app= Flask(__name__)
@app.before_request
def br():
print('before_request')
@app.after_request
def ar(response:Response):
print('after_request')
return response
@app.before_first_request
def bfr():
print('before_first_request')
@app.teardown_request
def tr(error):
print('reardown_request:%s'%error)
@app.route('/')
def index():
print('执行视图函数')
# a=1/0 执行此命令则不会调用before_request钩子
return 'index'
if __name__ =='__main__':
app.run()
运行结果:
before_first_request
before_request
执行视图函数
after_request
reardown_request:None
127.0.0.1 - - [18/Mar/2020 10:50:48] "GET / HTTP/1.1" 200 -
--------- project # 工程目录
|------ main.py # 启动文件
|------ user # 用户模块
| |--- __init__.py # 包的初始化文件, 此处创建蓝图对象
| |--- views.py # 视图文件
| |--- ...
|
|------ home # 首页模块
| |--- __init__.py
| |--- views.py
| |--- ...
|...
from flask import Blueprint
home_blu = Blueprint('home_b',__name__) #创建蓝图
# home_blu:蓝图对象,home_b:蓝图名
from . import views # 导入视图文件
from home import home_blu
@home_blu.route('/') #路由不再通过app.route()创建,而是通过蓝图对象.route()来创建
def index():
return 'index'
from flask import Flask
from home import home_blu #导入蓝图
app = Flask(__name__)
app.register_blueprint(bome_blu) #注册蓝图
if __name__=='__main__':
print(app.url_map)
app.run()
运行结果:
Map([<Rule '/' (GET, OPTIONS, HEAD) -> home_b.index>,
<Rule '/static/' (GET, OPTIONS, HEAD) -> static>])
127.0.0.1 - - [18/Mar/2020 12:01:22] "GET / HTTP/1.1" 200 -
from flask import Blueprint
home_blu = Blueprint('home_b',__name__,url_prefix='/home')
# url_prefix参数用来给url添加统一资源前缀
@home_blu.before_request #使用蓝图对象创建钩子
def home_prepare():
print('home_before_request')
from . import views
from flask import url_for
from home import home_blu
@home_blu.route('/demo1') #路由/home/demo1
def demo1():
return 'demo1'
@home_blu.route('/demo2') #路由/home/demo2
def demo2()
url1=url_for('home_b.demo1')
print(url1)
print('demo2')
return 'demo2'
运行结果:
Map([<Rule '/home/demo1' (OPTIONS, HEAD, GET) -> home_b.demo1>,
<Rule '/home/demo2' (OPTIONS, HEAD, GET) -> home_b.demo2>,
<Rule '/static/' (OPTIONS, HEAD, GET) -> static>])
home_before_request
demo1
127.0.0.1 - - [18/Mar/2020 12:15:56] "GET /home/demo1 HTTP/1.1" 200 -
home_before_request
/home/demo1
demo2
127.0.0.1 - - [