forked from orbit-oss/flask
Updated the documentation to show how to set cookies for not yet existing responses
This commit is contained in:
parent
7331ae3df5
commit
b40af3ccd9
3 changed files with 78 additions and 0 deletions
73
docs/patterns/deferredcallbacks.rst
Normal file
73
docs/patterns/deferredcallbacks.rst
Normal file
|
|
@ -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
|
||||||
|
|
@ -36,3 +36,4 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
|
||||||
mongokit
|
mongokit
|
||||||
favicon
|
favicon
|
||||||
streaming
|
streaming
|
||||||
|
cookies
|
||||||
|
|
|
||||||
|
|
@ -621,6 +621,10 @@ just return strings from the view functions Flask will convert them into
|
||||||
response objects for you. If you explicitly want to do that you can use
|
response objects for you. If you explicitly want to do that you can use
|
||||||
the :meth:`~flask.make_response` function and then modify it.
|
the :meth:`~flask.make_response` function and then modify it.
|
||||||
|
|
||||||
|
Sometimes you might want to set a cookie at a point where the response
|
||||||
|
object does not exist yet. This is possible by utilizing the
|
||||||
|
:ref:`deferred-callbacks` pattern.
|
||||||
|
|
||||||
For this also see :ref:`about-responses`.
|
For this also see :ref:`about-responses`.
|
||||||
|
|
||||||
Redirects and Errors
|
Redirects and Errors
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue