-
-
Notifications
You must be signed in to change notification settings - Fork 16.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated the documentation to show how to set cookies for not yet exis…
…ting responses
- Loading branch information
Showing
3 changed files
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
.. _deferred-callbacks: | ||
|
||
Deferred Request Callbacks | ||
========================== | ||
|
||
One of the design principles of Flask is that response objects are created | ||
and passed down a chain of potential callbacks that can modify them or | ||
replace them. When the request handling starts, there is no response | ||
object yet. It is created as necessary either by a view function or by | ||
some other component in the system. | ||
|
||
But what happens if you want to modify the response at a point where the | ||
response does not exist yet? A common example for that would be a | ||
before-request function that wants to set a cookie on the response object. | ||
|
||
One way is to avoid the situation. Very often that is possible. For | ||
instance you can try to move that logic into an after-request callback | ||
instead. Sometimes however moving that code there is just not a very | ||
pleasant experience or makes code look very awkward. | ||
|
||
As an alternative possibility you can attach a bunch of callback functions | ||
to the :data:`~flask.g` object and call then at the end of the request. | ||
This way you can defer code execution from anywhere in the application. | ||
|
||
|
||
The Decorator | ||
------------- | ||
|
||
The following decorator is the key. It registers a function on a list on | ||
the :data:`~flask.g` object:: | ||
|
||
from flask import g | ||
|
||
def after_this_request(f): | ||
if not hasattr(g, 'after_request_callbacks'): | ||
g.after_request_callbacks = [] | ||
g.after_request_callbacks.append(f) | ||
return f | ||
|
||
|
||
Calling the Deferred | ||
-------------------- | ||
|
||
Now you can use the `after_this_request` decorator to mark a function to | ||
be called at the end of the request. But we still need to call them. For | ||
this the following function needs to be registered as | ||
:meth:`~flask.Flask.after_request` callback:: | ||
|
||
@app.after_request | ||
def call_after_request_callbacks(response): | ||
for callback in getattr(g, 'after_request_callbacks', ()): | ||
response = callback(response) | ||
return response | ||
|
||
|
||
A Practical Example | ||
------------------- | ||
|
||
Now we can easily at any point in time register a function to be called at | ||
the end of this particular request. For example you can remember the | ||
current language of the user in a cookie in the before-request function:: | ||
|
||
from flask import request | ||
|
||
@app.before_request | ||
def detect_user_language(): | ||
language = request.cookies.get('user_lang') | ||
if language is None: | ||
language = guess_language_from_request() | ||
@after_this_request | ||
def remember_language(response): | ||
response.set_cookie('user_lang', language) | ||
g.language = language |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,3 +36,4 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_. | |
mongokit | ||
favicon | ||
streaming | ||
cookies |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters