### 導航
- [索引](# "總目錄")
- [下一頁](# "Flask Changelog") |
- [上一頁](# "Python 3 支持") |
- [Flask 0.10.1 文檔](#) ?
# 升級到最新版本
Flask 如同其它軟件一樣,會隨著時間不停地更新自己,其中大部分都會是非常體貼的,你無需改動一行自身代碼就可以應用新版本的 Flask。
不過,每當 Flask 有更新時,我們都建議你適當地修改自己的代碼,以充分地利用這些新功能,提高自己代碼地質量。
本章節文檔為您列舉了 Flask 各版本之間地差異,以及你如何修改自身代碼才能無痛地升級。
如果你使用 easy_install 命令更新、安裝 Flask,確保命令中包括 -U 參數
~~~
$ easy_install -U Flask
~~~
### Version 0.10
版本 0.9 到 0.10 最大變化在于 cookie 序列化格式從 pickle 轉變為了專門的 JSON 格式,這一更新是為了避免密鑰丟失時遭受黑客攻擊帶來損失。在更新是你會注意到以下兩大主要變化:all sessions that were issued before the upgrade are invalidated and you canonly store a limited amount of types in the session. The new sessions areby design much more restricted to only allow JSON with a few smallextensions for tuples and strings with HTML markup.
為了避免破壞用戶的 session 數據,你可以使用 Flask 擴展 Flask-OldSessions_ 來代替原先的 session。
### Version 0.9
從函數中返回元組的操作被簡化了,返回元組時你不再需要為你創建的 response 對象定義參數了,The behavior of returning tuples from a function was simplified. If youreturn a tuple it no longer defines the arguments for the response objectyou're creating, it's now always a tuple in the form (response,status,headers) where at least one item has to be provided.如果你的代碼依賴于舊版本,可以通過創建 Flask 的子類簡單地解決這個問題
~~~
class TraditionalFlask(Flask):
def make_response(self, rv):
if isinstance(rv, tuple):
return self.response_class(*rv)
return Flask.make_response(self, rv)
~~~
如果你維護的擴展曾使用 [_request_ctx_stack](# "flask._request_ctx_stack") ,可以考慮降至替換為[_app_ctx_stack](# "flask._app_ctx_stack"),但仍須檢查是否可行。例如,對于操作數據的擴展來說,app context stack更說得通,在請求無關的用例中使用它比 request stack 處理起來更容易。
### Version 0.8
Flask introduced a new session interface system. We also noticed thatthere was a naming collision between flask.session the module thatimplements sessions and [flask.session](# "flask.session") which is the global sessionobject. With that introduction we moved the implementation details forthe session system into a new module called flask.sessions. If youused the previously undocumented session support we urge you to upgrade.
If invalid JSON data was submitted Flask will now raise a[BadRequest](http://werkzeug.pocoo.org/docs/exceptions/#werkzeug.exceptions.BadRequest "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/exceptions/#werkzeug.exceptions.BadRequest] exception instead of letting thedefault [ValueError](http://docs.python.org/dev/library/exceptions.html#ValueError "(在 Python v3.5)") [http://docs.python.org/dev/library/exceptions.html#ValueError] bubble up. This has the advantage that you nolonger have to handle that error to avoid an internal server error showingup for the user. If you were catching this down explicitly in the pastas ValueError you will need to change this.
Due to a bug in the test client Flask 0.7 did not trigger teardownhandlers when the test client was used in a with statement. This wassince fixed but might require some changes in your testsuites if yourelied on this behavior.
### Version 0.7
In Flask 0.7 we cleaned up the code base internally a lot and did somebackwards incompatible changes that make it easier to implement largerapplications with Flask. Because we want to make upgrading as easy aspossible we tried to counter the problems arising from these changes byproviding a script that can ease the transition.
The script scans your whole application and generates an unified diff withchanges it assumes are safe to apply. However as this is an automatedtool it won't be able to find all use cases and it might miss some. Weinternally spread a lot of deprecation warnings all over the place to makeit easy to find pieces of code that it was unable to upgrade.
We strongly recommend that you hand review the generated patchfile andonly apply the chunks that look good.
If you are using git as version control system for your project werecommend applying the patch with path-p1<patchfile.diff and thenusing the interactive commit feature to only apply the chunks that lookgood.
To apply the upgrade script do the following:
1.
Download the script: [flask-07-upgrade.py](https://raw.github.com/mitsuhiko/flask/master/scripts/flask-07-upgrade.py) [https://raw.github.com/mitsuhiko/flask/master/scripts/flask-07-upgrade.py]
1.
Run it in the directory of your application:
~~~
python flask-07-upgrade.py > patchfile.diff
~~~
1.
Review the generated patchfile.
1.
Apply the patch:
~~~
patch -p1 < patchfile.diff
~~~
1.
If you were using per-module template folders you need to move sometemplates around. Previously if you had a folder named templatesnext to a blueprint named admin the implicit template pathautomatically was admin/index.html for a template file calledtemplates/index.html. This no longer is the case. Now you needto name the template templates/admin/index.html. The tool willnot detect this so you will have to do that on your own.
Please note that deprecation warnings are disabled by default startingwith Python 2.7. In order to see the deprecation warnings that might beemitted you have to enabled them with the [warnings](http://docs.python.org/dev/library/warnings.html#module-warnings "(在 Python v3.5)") [http://docs.python.org/dev/library/warnings.html#module-warnings] module.
If you are working with windows and you lack the patch command lineutility you can get it as part of various Unix runtime environments forwindows including cygwin, msysgit or ming32. Also source control systemslike svn, hg or git have builtin support for applying unified diffs asgenerated by the tool. Check the manual of your version control systemfor more information.
### Bug in Request Locals
Due to a bug in earlier implementations the request local proxies nowraise a [RuntimeError](http://docs.python.org/dev/library/exceptions.html#RuntimeError "(在 Python v3.5)") [http://docs.python.org/dev/library/exceptions.html#RuntimeError] instead of an [AttributeError](http://docs.python.org/dev/library/exceptions.html#AttributeError "(在 Python v3.5)") [http://docs.python.org/dev/library/exceptions.html#AttributeError] when theyare unbound. If you caught these exceptions with [AttributeError](http://docs.python.org/dev/library/exceptions.html#AttributeError "(在 Python v3.5)") [http://docs.python.org/dev/library/exceptions.html#AttributeError]before, you should catch them with [RuntimeError](http://docs.python.org/dev/library/exceptions.html#RuntimeError "(在 Python v3.5)") [http://docs.python.org/dev/library/exceptions.html#RuntimeError] now.
Additionally the [send_file()](# "flask.send_file") function is now issuingdeprecation warnings if you depend on functionality that will be removedin Flask 1.0. Previously it was possible to use etags and mimetypeswhen file objects were passed. This was unreliable and caused issuesfor a few setups. If you get a deprecation warning, make sure toupdate your application to work with either filenames there or disableetag attaching and attach them yourself.
Old code:
~~~
return send_file(my_file_object)
return send_file(my_file_object)
~~~
New code:
~~~
return send_file(my_file_object, add_etags=False)
~~~
### Upgrading to new Teardown Handling
We streamlined the behavior of the callbacks for request handling. Forthings that modify the response the [after_request()](# "flask.Flask.after_request")decorators continue to work as expected, but for things that absolutelymust happen at the end of request we introduced the new[teardown_request()](# "flask.Flask.teardown_request") decorator. Unfortunately thatchange also made after-request work differently under error conditions.It's not consistently skipped if exceptions happen whereas previously itmight have been called twice to ensure it is executed at the end of therequest.
If you have database connection code that looks like this:
~~~
@app.after_request
def after_request(response):
g.db.close()
return response
~~~
You are now encouraged to use this instead:
~~~
@app.teardown_request
def after_request(exception):
if hasattr(g, 'db'):
g.db.close()
~~~
On the upside this change greatly improves the internal code flow andmakes it easier to customize the dispatching and error handling. Thismakes it now a lot easier to write unit tests as you can prevent closingdown of database connections for a while. You can take advantage of thefact that the teardown callbacks are called when the response context isremoved from the stack so a test can query the database after requesthandling:
~~~
with app.test_client() as client:
resp = client.get('/')
# g.db is still bound if there is such a thing
# and here it's gone
~~~
### Manual Error Handler Attaching
While it is still possible to attach error handlers toFlask.error_handlers it's discouraged to do so and in factdeprecated. In generaly we no longer recommend custom error handlerattaching via assignments to the underlying dictionary due to the morecomplex internal handling to support arbitrary exception classes andblueprints. See Flask.errorhandler() for more information.
The proper upgrade is to change this:
~~~
app.error_handlers[403] = handle_error
~~~
Into this:
~~~
app.register_error_handler(403, handle_error)
~~~
Alternatively you should just attach the function with a decorator:
~~~
@app.errorhandler(403)
def handle_error(e):
...
~~~
(Note that register_error_handler() is new in Flask 0.7)
### Blueprint Support
Blueprints replace the previous concept of “Modules” in Flask. Theyprovide better semantics for various features and work better with largeapplications. The update script provided should be able to upgrade yourapplications automatically, but there might be some cases where it failsto upgrade. What changed?
- Blueprints need explicit names. Modules had an automatic nameguesssing scheme where the shortname for the module was taken from thelast part of the import module. The upgrade script tries to guessthat name but it might fail as this information could change atruntime.
- Blueprints have an inverse behavior for url_for(). Previously.foo told url_for() that it should look for the endpointfoo on the application. Now it means “relative to current module”.The script will inverse all calls to url_for() automatically foryou. It will do this in a very eager way so you might end up withsome unnecessary leading dots in your code if you're not usingmodules.
- Blueprints do not automatically provide static folders. They willalso no longer automatically export templates from a folder calledtemplates next to their location however but it can be enabled fromthe constructor. Same with static files: if you want to continueserving static files you need to tell the constructor explicitly thepath to the static folder (which can be relative to the blueprint'smodule path).
- Rendering templates was simplified. Now the blueprints can providetemplate folders which are added to a general template searchpath.This means that you need to add another subfolder with the blueprint'sname into that folder if you want blueprintname/template.html asthe template name.
If you continue to use the Module object which is deprecated, Flask willrestore the previous behavior as good as possible. However we stronglyrecommend upgrading to the new blueprints as they provide a lot of usefulimprovement such as the ability to attach a blueprint multiple times,blueprint specific error handlers and a lot more.
### Version 0.6
Flask 0.6 comes with a backwards incompatible change which affects theorder of after-request handlers. Previously they were called in the orderof the registration, now they are called in reverse order. This changewas made so that Flask behaves more like people expected it to work andhow other systems handle request pre- and postprocessing. If youdepend on the order of execution of post-request functions, be sure tochange the order.
Another change that breaks backwards compatibility is that contextprocessors will no longer override values passed directly to the templaterendering function. If for example request is as variable passeddirectly to the template, the default context processor will not overrideit with the current request object. This makes it easier to extendcontext processors later to inject additional variables without breakingexisting template not expecting them.
### Version 0.5
Flask 0.5 is the first release that comes as a Python package instead of asingle module. There were a couple of internal refactoring so if youdepend on undocumented internal details you probably have to adapt theimports.
The following changes may be relevant to your application:
- autoescaping no longer happens for all templates. Instead it isconfigured to only happen on files ending with .html, .htm,.xml and .xhtml. If you have templates with differentextensions you should override the[select_jinja_autoescape()](# "flask.Flask.select_jinja_autoescape") method.
- Flask no longer supports zipped applications in this release. Thisfunctionality might come back in future releases if there is demandfor this feature. Removing support for this makes the Flask internalcode easier to understand and fixes a couple of small issues that makedebugging harder than necessary.
- The create_jinja_loader function is gone. If you want to customizethe Jinja loader now, use the[create_jinja_environment()](# "flask.Flask.create_jinja_environment") method instead.
### Version 0.4
For application developers there are no changes that require changes inyour code. In case you are developing on a Flask extension however, andthat extension has a unittest-mode you might want to link the activationof that mode to the new TESTING flag.
### Version 0.3
Flask 0.3 introduces configuration support and logging as well ascategories for flashing messages. All these are features that are 100%backwards compatible but you might want to take advantage of them.
### Configuration Support
The configuration support makes it easier to write any kind of applicationthat requires some sort of configuration. (Which most likely is the casefor any application out there).
If you previously had code like this:
~~~
app.debug = DEBUG
app.secret_key = SECRET_KEY
~~~
You no longer have to do that, instead you can just load a configurationinto the config object. How this works is outlined in [*配置處理*](#).
### Logging Integration
Flask now configures a logger for you with some basic and useful defaults.If you run your application in production and want to profit fromautomatic error logging, you might be interested in attaching a proper loghandler. Also you can start logging warnings and errors into the loggerwhen appropriately. For more information on that, read[*記錄應用錯誤*](#).
### Categories for Flash Messages
Flash messages can now have categories attached. This makes it possibleto render errors, warnings or regular messages differently for example.This is an opt-in feature because it requires some rethinking in the code.
Read all about that in the [*消息閃現*](#) pattern.
? 版權所有 2013, Armin Ronacher.
- 歡迎使用 Flask
- 前言
- 給有經驗程序員的前言
- 安裝
- 快速入門
- 教程
- 介紹 Flaskr
- 步驟 0: 創建文件夾
- 步驟 1: 數據庫模式
- 步驟 2: 應用設置代碼
- 步驟 3: 創建數據庫
- 步驟 4: 請求數據庫連接
- 步驟 5: 視圖函數
- 步驟 6: 模板
- 步驟 7: 添加樣式
- 福利: 應用測試
- 模板
- 測試 Flask 應用
- 記錄應用錯誤
- 配置處理
- 信號
- 即插視圖
- 應用上下文
- 請求上下文
- 用藍圖實現模塊化的應用
- Flask 擴展
- 與 Shell 共舞
- Flask 代碼模式
- 大型應用
- 應用程序的工廠函數
- 應用調度
- 使用 URL 處理器
- 部署和分發
- 使用 Fabric 部署
- 在 Flask 中使用 SQLite 3
- 在 Flask 中使用 SQLAlchemy
- 上傳文件
- 緩存
- 視圖裝飾器
- 使用 WTForms 進行表單驗證
- 模板繼承
- 消息閃現
- 用 jQuery 實現 Ajax
- 自定義錯誤頁面
- 延遲加載視圖
- 在 Flask 中使用 MongoKit
- 添加 Favicon
- 數據流
- 延遲請求回調
- 添加 HTTP Method Overrides
- 請求內容校驗碼
- 基于 Celery 的后臺任務
- 部署選擇
- mod_wsgi (Apache)
- 獨立 WSGI 容器
- uWSGI
- FastCGI
- CGI
- 聚沙成塔
- API
- JSON 支持
- Flask 中的設計決策
- HTML/XHTML 常見問題
- 安全注意事項
- Flask 中的 Unicode
- Flask 擴展開發
- Pocoo 風格指引
- Python 3 支持
- 升級到最新版本
- Flask Changelog
- 許可證
- 術語表