flask
flask介绍
小而精,所有web开发需要的东西,借助于第三方集成
flask框架:Werkzeug WSGI工具包和Jinja2模板引擎
python-dotenv
# pip install python-dotenv
import os
from dotenv import load_dotenv
from dotenv import dotenv_values
## 1 加载配置文件
# 必须在根路径下新建一个 .env 的文件,并写入配置才能返回True,会把.env下的配置文件设置进环境变量
res=load_dotenv() # take environment variables from .env
print(res)
print(os.environ.get('DOMAIN'))
# You will probably want to add .env to your .gitignore, especially if it contains secrets like a password.
## 2 获取环境变量字典
config = dotenv_values(".env")
print(config)
print(config.get('DOMAIN'))
watchdog
# pip install watchdog
# 当前目录下文件修改会被监控到,打印日志
import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
虚拟环境
Mac/linux
# 创建虚拟环境
mkdir myproject
cd myproject
python3 -m venv .venv
# 激活虚拟环境
. .venv/bin/activate
Win
# 创建虚拟环境
mkdir myproject
cd myproject
py -3 -m venv .venv
# 激活虚拟环境
.venv\Scripts\activate
快速入门
安装
pip install Flask
运行flask项目
配置路由和视图函数对应关系--》基于装饰器
- 方式一: python -m flask --app app名 run
# app1.py
from flask import Flask
app=Flask(__name__)
# @app.route('/',methods=['GET'])
@app.get('/')
def index():
return 'hello flask'
- 方式二: flask --app app名 run
# app2.py
from flask import Flask
app=Flask(__name__)
@app.get('/')
def index():
return 'hello flask'
方式三: flask run --host=0.0.0.0
py文件必须叫app.py
# app.py
from flask import Flask
app=Flask(__name__)
@app.get('/')
def index():
return 'hello flask'
方式四:使用pycharm快速运行 配置一个 flaskserver
from flask import Flask
app=Flask(__name__)
@app.get('/')
def index():
return 'hello flask'
方式五:直接右键运行
from flask import Flask
app=Flask(__name__)
@app.get('/')
def index():
return 'hello flask'
if __name__ == '__main__':
app.run()
debug 模式
# 运行时,开启debug模式
flask --app hello run --debug
# debug模式
-自动重启
-错误提示
基本使用
1 返回新手四件套
- 返回字符串--》return '字符串'
- 返回模板--》render_template('detail.html',info=user)
- 返回重定向--》redirect('/login')
- 返回json--》jsonify({'code':100,'msg':'成功'})
2 request对象
request对象,是全局的
from flask import request
request.method 提交的方法
request.args get请求提及的数据
request.form post请求提交的数据
request.values post和get提交的数据总和
request.cookies 客户端所带的cookie
request.headers 请求头
request.path 不带域名,请求路径
request.full_path 不带域名,带参数的请求路径
request.script_root
request.url 带域名带参数的请求路径
request.base_url 带域名请求路径
request.url_root 域名
request.host_url 域名
3 前端传入的:请求体 请求参数
-请求体:request.form--->编码格式是 urlencoded
-请求参数:request.args-->路径后的 /home?name=qcc&age=22
4 渲染模板
-它比django更强大
-可以加括号
-字典可以.get []
-for {{}}
5 session使用
-设置 app.secret_key='adsfa33w48855r434l'
- 设置值:session['username']
- 取值:session.get('username')
6 路由转换器
@app.get('/')
@app.route('/', methods=['GET'])
@app.route('/detail/<int:pk>', methods=['GET'])
7 登录认证装饰器
登录装饰器放下面
方式一:使用 装饰器 装饰 装饰器 @wraps(func)
from functools import wraps
# 用户登录,写个装饰器
def login_required(func):
@wraps(func)
def inner(*args, **kw):
# 判断有没有登录
if session.get('username'):
res = func(*args, **kw)
return res
else:
return redirect('/login')
return inner
@app.route('/', methods=['GET'])
@login_required
def index():
return render_template('index.html')
方式二: 给每个@app都指定别名( 添加唯一的endpoint值)
from functools import wraps
def login_required(func):
def inner(*args, **kw):
if session.get('username'):
res = func(*args, **kw)
return res
else:
return redirect('/login')
return inner
@app.route('/', methods=['GET'],endpoint='index')
@login_required
def index():
return render_template('index.html')
请求对象
# request.method 提交的方法
# request.args get请求提及的数据
# request.form post请求提交的数据
# request.values post和get提交的数据总和
# request.cookies 客户端所带的cookie
# request.headers 请求头
# request.path 不带域名,请求路径
# request.full_path 不带域名,带参数的请求路径
# request.script_root
# request.url 带域名带参数的请求路径
# request.base_url 带域名请求路径
# request.url_root 域名
# request.host_url 域名
# request.host 127.0.0.1:500
# request.files
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename))
响应对象
from flask import Flask, url_for, request,make_response,jsonify
from flask.views import MethodView, View
app = Flask(__name__)
app.debug = True
class IndexView(MethodView):
def get(self):
# 1 新手四件套:字符串,模板,重定向,json
# 2 向cookie中写入数据
res=make_response('get请求') # make_response 放四件套之一都可
res.set_cookie('key','xxx',httponly=True,path='/')
# 3 向响应头中写入数据
res.headers['xxxx']='sss'
return res
def post(self):
return 'post请求'
app.add_url_rule('/index', view_func=IndexView.as_view(name='xxx')) #
if __name__ == '__main__':
app.run()
请求扩展
flask中叫请求扩展---》本质作用实现像django中间件的作用一样
1 before_request
from flask import Flask
app=Flask(__name__)
# 1 请求来进视图函数之前执行
# 2 多个会从上往下依次执行
# 3 如果返回None,表示继续下一个
# 4 如果返回了四件套:表示结束,不继续往后走
@app.before_request
def before01():
print('来了老弟')
@app.get('/')
def index():
return 'ok'
if __name__ == '__main__':
app.run()
2 after_request
from flask import Flask
app=Flask(__name__)
# 1 视图函数执行完,走
# 2 多个会从下往上依次执行
# 3 必须有返回值,是响应对象
# 4 处理跨域,再响应头中加--》就用它
@app.get('/')
def index():
print('index')
return 'ok'
@app.after_request
def before0(response):
print('走了')
return response
if __name__ == '__main__':
app.run()
3 teardown_request
from flask import Flask
app=Flask(__name__)
# 1 无论视图函数执行成功或失败,都会走它
# 2 即便视图函数执行出异常, 也会走
# 3 一般用来记录日志
@app.get('/')
def index():
print('index')
return 'ok'
@app.teardown_request
def teardown(exc):
# exc是视图函数错误对象--》记录错误日志
print(exc)
if __name__ == '__main__':
app.run()
4 errorhandler
from flask import Flask, jsonify
app=Flask(__name__)
@app.get('/')
def index():
print('index')
return 'ok'
# 1 监听http响应状态码
# 2 全局异常处理
@app.errorhandler(404)
def error_404(arg):
return jsonify({'code':'xxx'})
@app.errorhandler(500)
def error_500(arg):
return jsonify({'code':'500错误了'})
if __name__ == '__main__':
app.run()
偏函数----提前传值
from functools import partial
def add(a,b,c):
return a+b+c
res=add(1,2,3)
print(res)
res=partial(add,1) # 提前传值
print(res(2,3))
蓝图(blueprint)
蓝图使用步骤:
1 蓝图类实例化得到一个对象
from flask import Blueprint
# 第一个参数是蓝图名
order_blue=Blueprint('order',__name__)
2 在视图函数上,使用蓝图注册路由-->蓝图也有请求扩展
@order_blue.before_request
def before():
print('来了')
@order_blue.route('/order')
def order():
return 'order-order-order'
3 在app中注册蓝图
app.register_blueprint(user_blue)