Browse Source

Updated the documentation to show how to set cookies for not yet existing responses

pull/322/head
Armin Ronacher 13 years ago
parent
commit
b40af3ccd9
  1. 73
      docs/patterns/deferredcallbacks.rst
  2. 1
      docs/patterns/index.rst
  3. 4
      docs/quickstart.rst

73
docs/patterns/deferredcallbacks.rst

@ -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

1
docs/patterns/index.rst

@ -36,3 +36,4 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
mongokit mongokit
favicon favicon
streaming streaming
cookies

4
docs/quickstart.rst

@ -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…
Cancel
Save