Flask学习笔记
一、基础知识
- pipenv下的包管理
# 安装 pipenv 包
pip install pipenv
# 更改配置信息保存位置,默认保存在 USER_HOME\.virtualenvs,改为保存到项目文件夹下
# linux
export PIPENV_VENV_IN_PROJECT=1
# windows
# 创建 PIPENV_VENV_IN_PROJECT 环境变量,值为 1
# 在指定文件夹下建立虚拟环境,如果已存在 PipFile,则安装其中指定的依赖包
cd myproject
pipenv install
# 进入虚拟环境
cd myproject
pipenv shell
# 在虚拟环境中安装包
pipenv install xxxx
# 虚拟环境中升级包
pipenv updata xxxx
# 退出虚拟环境
exit
在 pipenv 下安装包必须通过 pipenv install 包名 来安装,这样才会将包依赖添加到 pipfile.lock 中,复制源代码到新环境后执行 pipenv install 将自动安装需要的依赖包。如果在 pipenv shell 下执行 pip install 包名 ,将无法在新环境下通过 pipenv install 安装依赖包——尽管 pipenv graph 可以正常显示包依赖。
- 环境变量管理
pipenv install python-dotenv,在项目根目录下新建.env(用于保存私密环境变量),.flaskenv(用于保存公开环境变量),执行flask run时会自动加载两个文件中的环境变量。
# 指定主模块文件名,执行 flask run 时加载该文件
FLASK_APP="app"
FLASK_RUN_PORT=5000
# 对外监听
FLASK_RUN_HOST="0.0.0.0"
# 开发环境(输出调试信息),production 为生产环境,未来版本将弃用
FLASK_ENV=development
# 开启调试器(开发环境下自动开启)
FLASK_DEBUT=1
# 在程序中读取环境变量
import os
app.secret_key = os.getenv('SECRET_KEY', 'default key');
- 文件更新监视
pipenv install watchdog --dev,安装到开发环境,生产环境下不安装。修改文件并保存后自动重启服务。
二、Flask与HTTP
- request对象
# 获取URL中的查询参数,以 localhost:5000/index?pwd=1234&name=admin 为例
name = flask.request.args.get("name", "")
# 返回 /index
path = flask.request.path
# 返回 /index?pwd=1234&name=admin
full_path = flask.request.full_path
# 返回 localhost:5000/index?pwd=1234&name=admin
url = flask.request.url
- URL中的转换规则
# 在URL中夹入变量并传递到函数中
@app.route('/calc/<int:i>')
def calc(i): # 这里的形参名称必须与URL中定义的参数名称完全一致,变量类型与变量名之间的冒号前后不能有多余的空格
return i * i
# 匹配列表中的一个元素,如果无法匹配则返回 404 错误
@app.route('/colors/<any(red, green, blue):color>')
# 其余可用类型:
# string 不含斜线的字符串(默认类型)
# float
# path 含斜线的字符串
- 请求钩子
@app.before_request # 在处理第一个请求前执行
def do_somethine():
pass
@app.before_first_request # 在处理每个请求前执行
@app.after_request # 无异常抛出则在每个请求结束后执行
@app.teardown_request # 在每个请求结束后执行,如果有异常未处理,会将异常作为参数传入到注册的函数中
@app.after_this_request # 在视图函数中注册一个函数,会在这个请求结束后执行
- 重定向
# 注意!url_for传入的参数应该是 函数名 而不是 URL 名
return flask.redirect(flask.url_for('say_hello'))
- 错误响应
def not_found():
abort(404) # 此后的代码将不再执行
- cookie管理
# 重定向到 say_hello 函数并设置 cookie
respones = flask.make_response(flask.redirect(flask.url_for('say_hello')))
respones.set_cookie('username', name)
# 读取 cookie 值
name = flask.request.cookies.get('username', '')
- session
app = Flask(__name__)
# 从环境变量中读取并设置 session 的加密密钥
app.secret_key = os.getenv('SECRET_KEY', 'aaa')
# 写入 session
flask.session['uname'] = 'zhang'
# 读取 session 中保存的值
name = flask.session.get('uname', '')
# 查询 session 中是否包含指定项
if 'uname' not in flask.session:
abort(403)
- Flask 上下文
程序上下文 current_app,g
请求上下文 request, session
@app.before_request
def set_name():
# 保存到程序上下文,相当于全局变量
flask.g.uname = flask.request.args.get('name')
- 重定向并自动返回
import urllib # python2 需要导入 urlparse
def is_safe_url(target_url):
ref_url = urllib.parse.urlparse(flask.request.host_url)
test_url = urllib.parse.urlparse(urllib.parse.urljoin(flask.request.host_url, target_url))
return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc
# 通用的返回函数
def redirect_back(default='say_hello', **kwargs):
for target in flask.request.args.get('next'), flask.request.referrer:
# 如果发起时夹带了返回地址
if target and is_safe_url(target):
return flask.redirect(target)
return flask.redirect(flask.url_for(default, **kwargs))
# 发起时
if not logined:
# 去往登录页面,next 指定了登录后自动返回本页面
return flask.redirect(flask.url_for('login', next=flask.request.full_path))
# 处理后跳转回原页面
def login():
...
return redirect_back()
多表查询(以 Article、Author 两表为例)
u = Article.query.join(Author).add_entity(Author)
title = u[0].Article.title
name = u[0].Author.name

浙公网安备 33010602011771号