repr函數代替str函數
def __repr__(self):
return "直接輸出&print調用"
創建數據庫
CREATE DATABASE my_database default charset utf8 COLLATE utf8_general_ci;
GRANT ALL ON my_database.* TO 'username'@'127.0.0.1' IDENTIFIED BY 'pass_word';
GRANT ALL ON my_database.* TO 'username'@'localhost' IDENTIFIED BY 'pass_word';
GRANT ALL ON my_database.* TO 'username'@'%' IDENTIFIED BY 'pass_word';
修改默認的靜態文件目錄
app = Flask(__name__, static_folder='files')
錯誤處理
使用”abort()”函數可以直接退出請求,返回錯誤代碼:
from flask import abort
@app.route('/error')
def error():
abort(404)
上例會顯示瀏覽器的404錯誤頁面。有時候,我們想要在遇到特定錯誤代碼時做些事情,或者重寫錯誤頁面,可以用下面的方法:
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404
此時,當再次遇到404錯誤時,即會調用”page_not_found()”函數,其返回”404.html”的模板頁。第二個參數代表錯誤代碼。
更常見的方式
# 定義異常類
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=400):
Exception.__init__(self)
self.message = message
self.status_code = status_code
# 異常類響應事件
@app.errorhandler(InvalidUsage)
def invalid_usage(error):
response = make_response(error.message)
response.status_code = error.status_code
return response
# 拋出異常類的測試
@app.route('/exception')
def exception():
raise InvalidUsage('No privilege to access the resource', status_code=403)
URL重定向
作用就是當客戶端瀏覽某個網址時,將其導向到另一個網址。常見的例子,比如用戶在未登錄時瀏覽某個需授權的頁面,我們將其重定向到登錄頁要求其登錄先。
from flask import session, redirect
@app.route('/')
def index():
if 'user' in session:
return 'Hello %s!' % session['user']
else:
return redirect(url_for('login'), 302)
“redirect()”的第二個參數時HTTP狀態碼,可取的值有301, 302, 303, 305和307,默認即302
日誌處理
Flask提供logger對象,其是一個標準的Python Logger類。
@app.route('/exception')
def exception():
app.logger.debug('Enter exception method')
app.logger.error('403 error happened')
raise InvalidUsage('No privilege to access the resource', status_code=403)
在debug模式下,日誌會默認輸出到標準錯誤stderr中。你可以添加FileHandler來使其輸出到日誌文件中去,也可以修改日誌的記錄格式
server_log = TimedRotatingFileHandler('server.log','D')
server_log.setLevel(logging.DEBUG)
server_log.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s'
))
error_log = TimedRotatingFileHandler('error.log', 'D')
error_log.setLevel(logging.ERROR)
error_log.setFormatter(logging.Formatter(
'%(asctime)s: %(message)s [in %(pathname)s:%(lineno)d]'
))
app.logger.addHandler(server_log)
app.logger.addHandler(error_log)
另外,這裏使用了”TimedRotatingFileHandler”並給了參數”D”,這樣日誌每天會創建一個新的文件,並將舊文件加日期後綴來歸檔。
還可以將錯誤信息發送郵件。更詳細的日誌使用可參閱Python logging官方文檔。
消息閃現
“flash()”方法的第二個參數是消息類型,可選擇的有”message”, “info”, “warning”, “error”。你可以在獲取消息時,同時獲取消息類型,還可以過濾特定的消息類型。只需設置”get_flashed_messages()”方法的”with_categories”和”category_filter”參數即可。比如,Python部分可改爲:
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
session['user'] = request.form['user']
flash('Login successfully!', 'message')
flash('Login as user: %s.' % request.form['user'], 'info')
return redirect(url_for('index'))
layout模板部分可改爲:
{% with messages = get_flashed_messages(with_categories=true, category_filter=["message","error"]) %}
{% if messages %}
<ul class="flash">
{% for category, message in messages %}
<li class="{{ category }}">{{ category }}: {{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
加載配置
from flask import Flask
import config
app = Flask(__name__)
app.config.from_object('config')
請求上下文裝飾器
before_request可以有多個,按照從上到下的順序調用
after_request、teardown_request也可以有多個,按照從下到上的順序調用
g變量是一個應用上下文
@app.before_request
def before_request():
"""進入請求前執行,可以用來開啓數據庫連接"""
print('before request started')
print(request.url)
g.name="SampleApp"
@app.after_request
def after_request(response):
"""正常執行完請求時執行,接收response返回response"""
print('after request finished==============')
print(request.url)
response.headers['status'] = 'good1'
return response
@app.teardown_request
def teardown_request(exception):
"""不論是否正常執行完請求都執行,可以用來關閉數據庫連接"""
print('teardown request==============')
print(request.url)
print(exception)
靈活使用視圖類
from flask.views import MethodView
class RenderTemplateView(View):
decorators = [login_required] #視圖裝飾器
methods = ['GET', 'POST'] #默認只有GET
def __init__(self, template):
self.template = template
def dispatch_request(self):
return render_template(self.template)
app.add_url_rule('/hello', view_func=RenderTemplateView.as_view('hello', template='hello-view.html'))
app.add_url_rule('/login', view_func=RenderTemplateView.as_view('login', template='login-view.html'))
基於方法的視圖類
from flask.views import MethodView
class UserAPI(MethodView):
def get(self, user_id):
if user_id is None:
return 'Get User called, return all users'
else:
return 'Get User called with id %s' % user_id
def post(self):
return 'Post User called'
def put(self, user_id):
return 'Put User called with id %s' % user_id
def delete(self, user_id):
return 'Delete User called with id %s' % user_id
user_view = UserAPI.as_view('users')
app.add_url_rule('/users/', view_func=user_view, defaults={'user_id': None}, methods=['GET',])
app.add_url_rule('/users/', view_func=user_view, methods=['POST',])
app.add_url_rule('/users/<user_id>', view_func=user_view, methods=['GET', 'PUT', 'DELETE'])