pipenv的是配置与使用
链接: https://zhuanlan.zhihu.com/p/71598248.
链接: https://zhuanlan.zhihu.com/p/104935266.
创建程序实例
可以从flask包中导入Flask类,这个类表示一个Flask程序
from flask import Flask
app = Flask(__name__)
启动项目
pipenv run flask run
路由匹配
from flask import Flask
app = Flask(__name__name)
@app.route('/hello/<name>')
def hello(name):
# 如果url_for有动态部分,则直接传入参数
return 'hello %s!'%name
@app.route('/method', methods=['GET',POST])
def method():
name = request.args.get('name', 'Flask')
return 'hello %s!'%name
flask的URL变量转换器
转换器 | 说明 |
---|---|
string | 不包含斜线的字符串 |
int | 整型 |
float | 浮点数 |
path | 包含斜线的字符串.static路由的URL规则中的filename说明了这个转换器 |
uuid | UUID字符串 |
示例:
@app.route('/time/<int:year>')
def go_back(year):
return 'this is a %s' %year
flask请求钩子
钩子 | 说明 |
---|---|
before_first_request | 注册第一个函数,在处理第一个请求前运行 |
before_request | 注册一个函数,在处理每个请求前运行 |
after_request | 注册一个函数,如果未处理的异常抛出,会在每个请求结束后运行 |
tear_down_request | 注册一个函数,即使有未处理的异常,会在每个请求结束后运行.如果发生异常,会传入异常对象作为参数到注册的函数中 |
after_this_request | 在视图函数内注册函数,会在这个请求结束后运行 |
HTTP响应
HTTP响应状态码
状态码 | 原因短语 | 说明 |
---|---|---|
200 | OK | 请求正常处理 |
201 | Created | 请求被处理,并创建一个新资源 |
204 | No Content | 请求处理成功,但无内容返回 |
301 | Moved Permanently | 永久重定向 |
302 | Found | 临时性重定向 |
304 | Not Modified | 请求的资源未被修改,重定向到缓存的资源 |
400 | bad Request | 表示请求无效,即请求报文中存在错误 |
401 | unauthorized | 类似403,表示请求的资源需要获取授权信息,在浏览器中弹出认证弹窗 |
403 | Forbidden | 表示请求的资源被服务器拒绝访问 |
404 | Not Found | 表示在服务器上无法找到请求的资源或URL无效 |
500 | Internal Server Error | 服务器内部发生错误 |
1.重定向
@app.route('/redirect')
def redire() :
return redirect('http://www.baidu.com')
@app.route('/redi')
def hi():
return redirect(url_for('redire')) # 注意这里返回的是路由对应的函数名
@app.route('/404')
def not_found():
abort(404)
2.响应格式
MIME类型 | Content-Type:text/html;charset=utf-8 |
---|---|
text/plain | |
text/html | |
applicatioin/xml | |
application/json |
@app.route('/foo')
def foo():
data = {
'name':'Grey Li',
'gender':'male'
}
response = make_response(json.dumps(data))
response.mimetype = 'application/json'
return response
@app.route('/foo1')
def foo1():
return jsonify({'name':'Grey Li','gender':'male'})
3.Cookie
set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)
@app.route('/setname/<user>')
def set_cookie(user):
response =make_response(url_for('redire'))
response.set_cookie('user', user)
return response
@app.route('/usecookie')
def use_cookie():
name = request.args.get('name')
if name is None:
# 从cookie中获取name值
name = request.cookies.get('user', 'human')
return '<h1>hello, %s</h1>' % name
4.session
@app.route('/register')
def use_sessioin():
# 写入session
session['logged_in'] = True
return redirect(url_for('login'))
@app.route('/login')
def login():
name = request.args.get('name')
if name is None:
name = request.cookies.get('name', 'Human')
response = '<h1>Hello, %s!</h1>' %name
# 根据用户的认证返回不同的内容
if 'logged_in' in session:
response += '[Authenticated]'
else:
response += '[not Authenticated]'
return response
@app.route('/logout')
def logout():
if 'logged_in' in session:
session.pop('logged_in')
return redirect(url_for('login'))
Flask上下文
上下文全局变量
变量名 | 上下文类型 | 说明 |
---|---|---|
current_app | 程序上下文 | 只想处理请求的程序实例 |
g | 程序上下文 | 替代Python的全局变量用法,确保仅在当前请求中可用.用于存储全局数据,每次请求会重设 |
request | 请求上下文 | 封装客户端发出的请求报文数据 |
session | 请求上下文 | 用于记住请求之间的数据,通过签名的cookie实现 |
from flask import Flask,g
@app.before_request
def get_name():
g.name = 'abc'
激活上下文
- 使用flask run 命令启动程序时
- 是永久的app.run()方法启动程序时
- 执行使用@app.cli.command()装饰器注册的flask命令时
- 使用
flask shell
命令来启动Python Shell
当请求进入时,Flask会自动激活请求上下文.这时我们可以使用request和session变量
上下文钩子
提供了一种teardown_appcontext
钩子,它注册的回调函数会在程序上下文以及请求上下文被销毁时调用,比如,在请求结束后销毁数据库连接.
@app.teardown_appcontext
def teardown_db(exception):
db.close()
HTTP进阶
获取上一个页面的url
(1) HTTP referer
return redirect(request.referrer or url_for('hello))
# request.full_path , 获得所有的请求
模板
app = Flask(__name__, template_folder='templates', static_folder="****",static_url_path="****") 在最开始的这句话中,template_folder后面一定要跟上templates;
文件上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/upload" enctype ="multipart/form-data" method="post">
<input type="file" name="file"/>
<button type="submit">提交</button>
</form>
</body>
</html>
# 上传文件的路径
app.config['UPLOAD_PATH'] = os.path.join(app.root_path, 'uploads')
# 上传文件大小限制
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 *1000
# 上传文件的后缀名限制
ALLOWED_EXTENSIONS = { 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# 上传文件
@app.route('/upload', methods = ['get', 'post'])
def upload():
f = request.files['file']
if f and allowed_file(f.filename):
f.save(os.path.join(app.config['UPLOAD_PATH'] ,secure_filename(f.filename)))
else:
return 'file upload failed'
return "file upload success"
多文件上传
<form action="/multipleupload" enctype ="multipart/form-data" method="post">
<input type="file" name="filelist" multiple>
<button type="submit">提交</button>
</form>
@app.route('/multipleupload', methods = ['get', 'post'])
def multiple_upload():
files = request.files.getlist('filelist')
for f in files:
if f and allowed_file(f.filename):
f.save(os.path.join(app.config['UPLOAD_PATH'] ,secure_filename(f.filename)))
else:
return 'file upload failed'
return 'file upload success'
使用Flask-CKEditor集成富文本编辑器\
需要使用插件flask-ckeditor