笔记-flask基础操作
1. 前言
本文为flask基础学习及操作笔记,主要内容为flask基础操作及相关代码。
2. 开发环境配置
2.1. 编译环境准备
安装相关Lib
windows环境下:
cd ….venv/Scripts
active
pip install flask
2.2. pycharm配置
- 在setting中的编译器中新增编译器(指向venv中的Python文件)
- 在run/debug configure中使用新增的编译器。
3. 项目创建
3.1. 项目文件组织结构设计:
一个比较良好的flask项目结构
project/
app/ # 整个程序的包目录
static/ # 静态资源文件
js/ # JS脚本
css/ # 样式表
img/ # 图片
favicon.ico # 网站图标
templates/ # 模板文件
common/ # 通用模板
errors/ # 错误页面
user/ # 用户模板
posts/ # 帖子模板
email/ # 邮件发送
views/ # 视图文件
models/ # 数据模型
forms/ # 表单文件
config.py # 配置文件
email.py # 邮件发送
extensions.py # 各种扩展
migrations/ # 数据库迁移目录
tests/ # 测试单元
venv/ # 虚拟环境
dev_doc/ #开发文档
requirements.txt # 依赖包的列表
run.py # 项目启动控制文件
4. 常用功能
4.1. Flask对象声明及运行
file:app.py
from flask import Flask
app = Flask(__name__)
file:run.py
from website.app.app import app
if __name__ == '__main__':
app.run()
4.2. 调试模式
每次修改代码后需要重启服务器来使其生效,可以打开调试模式,服务器会在代码修改后自动重新载入,并在发生错误时提供更好的支持。
有两种方法打开调试模式:
app.debug = True
app.run()
或者
app.run(debug=True)
两者没什么不同
4.3. 路由
@app.route(‘/’)
关键词:变量,URL
4.4. 变量
在请求时需要传入参数,
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id
更详细内容见:笔记-flask-传参及返回格式化数据
4.5. 唯一URL /重定向行为
以下两条规则的不同之处在于是否使用尾部的斜杠。:
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
projects的URL是中规中举的,尾部有一个斜杠,看起来就如同一个文件夹。访问一个没有斜杠结尾的URL时Flask会自动进行重定向,帮你在尾部加上一个斜杠。
about的URL没有尾部斜杠,因此其行为表现与一个文件类似。如果访问这个URL时添加了尾部斜杠就会得到一个404错误。这样可以保持URL唯一,并帮助搜索引擎避免重复索引同一页面。
4.6. 构造url--url_for()
url_for()用于构建指定URL,它把函数名称作为第一个参数。
推荐使用url_for(),理由如下:
- 构造url比直接写可读性好;
- 自动生成,在修改时不用到处去修改相关代码;
- 自动生成的路径通常是绝对路径,可以避免一些问题;
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(username)
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
/
/login
/login?next=/
/user/John%20Doe
4.7. HTTP 方法
HTTP (与 Web 应用会话的协议)有许多不同的访问 URL 方法。默认情况下,路由只回应 GET 请求,但是通过 route() 装饰器传递 methods 参数可以改变这个行为。这里有一些例子:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
4.8. 静态文件
动态 web 应用也会需要静态文件,通常是 CSS 和 JavaScript 文件。理想状况下, 你已经配置好 Web 服务器来提供静态文件,但是在开发中,Flask 也可以做到。 只要在你的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问。
给静态文件生成 URL ,使用特殊的 'static' 端点名:
url_for('static', filename='style.css')
这个文件应该存储在文件系统上的 static/style.css 。
4.9. 模板渲染
用Python生成HTML十分无趣,而且相当繁琐,因为你必须手动对 HTML 做转义来保证应用的安全。为此,Flask 配备了 Jinja2 模板引擎。
可以使用 render_template() 方法来渲染模板。需要做的就是将模板名和传入模板的变量。
渲染模板的简例:
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
默认情况下Flask 会在 templates 文件夹里寻找模板。如果应用是个模板文件,这个文件夹应该与模板同级;如果它是一个包,那么这个文件夹作为包的子目录:
情况 1: 模块:
4.10. 重定向和错误
你可以用 redirect() 函数把用户重定向到其它地方。放弃请求并返回错误代码,用 abort() 函数。这里是一个它们如何使用的例子:
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
默认情况下,错误代码会显示一个黑白的错误页面。如果你要定制错误页面, 可以使用 errorhandler() 装饰器:
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
5. response
a view function 的返回值会被自动 converted into a response object for you.
转换规则如下:
- If a response object of the correct type is returned it’s directly returned from the view.
如果格式正确,直接返回;
- If it’s a string, a response object is created with that data and the default parameters.
如果是字符串,创建一个response obj;
- If a tuple is returned the items in the tuple can provide extra information. Such tuples have to be in the form (response,status, headers) or (response, headers) where at least one item has to be in the tuple. The status value will override the status code and headers can be a list or dictionary of additional header values.
如果返回的是一个元组,且无级中的元素遵守一定格式 (response,status, headers) or (response, headers) ,会按照元组提供的信息组成响应报文;
- If none of that works, Flask will assume the return value is a valid WSGI application and convert that into a response object.
If you want to get hold of the resulting response object inside the view you can use the make_response() function.
视图函数中手动生成响应报文案例:
@app.errorhandler(404)
def not_found(error):
return render_template('error.html'), 404
You just need to wrap the return expression with make_response() and get the response object to modify it, then return it:
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
6. sessions
除请求对象之外,还有一个 session 对象。如果对cookie有一定了解就很好理解,它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名。这意味着用户可以查看你 Cookie 的内容,但却不能修改它,除非用户知道签名的密钥。
要使用会话,你需要设置一个密钥。这里介绍会话如何工作:
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form action="" method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
这里提到的 escape() 可以在你模板引擎外做转义(如同本例)。
7. message flashing
flask.flash(message, category='message')
Flashes a message to the next request. In order to remove the flashed message from the session and to display it to the user, the template has to call get_flashed_messages().
代码实现:
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'secret':
error = 'Invalid credentials'
else:
flash('You were successfully logged in')
return redirect(url_for('index'))
return render_template('login.html', error=error)
8. 总结
上述章节仅为flask基本使用方法,可以用于对flask有一个基本的了解或是写一个简单的静态网站,还需要更多的学习;
简单flask web实现过程:
-
- 工程框架,配置文件,初始运行文件
- 创建flask类app
- 书写视图函数,包括路由和传参,请求类型
- 模板书写和渲染。