|
1 ====================== |
|
2 The messages framework |
|
3 ====================== |
|
4 |
|
5 .. module:: django.contrib.messages |
|
6 :synopsis: Provides cookie- and session-based temporary message storage. |
|
7 |
|
8 Django provides full support for cookie- and session-based messaging, for |
|
9 both anonymous and authenticated clients. The messages framework allows you |
|
10 to temporarily store messages in one request and retrieve them for display |
|
11 in a subsequent request (usually the next one). Every message is tagged |
|
12 with a specific ``level`` that determines its priority (e.g., ``info``, |
|
13 ``warning``, or ``error``). |
|
14 |
|
15 .. versionadded:: 1.2 |
|
16 The messages framework was added. |
|
17 |
|
18 Enabling messages |
|
19 ================= |
|
20 |
|
21 Messages are implemented through a :doc:`middleware </ref/middleware>` |
|
22 class and corresponding :doc:`context processor </ref/templates/api>`. |
|
23 |
|
24 To enable message functionality, do the following: |
|
25 |
|
26 * Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure |
|
27 it contains ``'django.contrib.messages.middleware.MessageMiddleware'``. |
|
28 |
|
29 If you are using a :ref:`storage backend <message-storage-backends>` that |
|
30 relies on :doc:`sessions </topics/http/sessions>` (the default), |
|
31 ``'django.contrib.sessions.middleware.SessionMiddleware'`` must be |
|
32 enabled and appear before ``MessageMiddleware`` in your |
|
33 :setting:`MIDDLEWARE_CLASSES`. |
|
34 |
|
35 * Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure |
|
36 it contains ``'django.contrib.messages.context_processors.messages'``. |
|
37 |
|
38 * Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS` |
|
39 setting |
|
40 |
|
41 The default ``settings.py`` created by ``django-admin.py startproject`` has |
|
42 ``MessageMiddleware`` activated and the ``django.contrib.messages`` app |
|
43 installed. Also, the default value for :setting:`TEMPLATE_CONTEXT_PROCESSORS` |
|
44 contains ``'django.contrib.messages.context_processors.messages'``. |
|
45 |
|
46 If you don't want to use messages, you can remove the |
|
47 ``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, the ``messages`` |
|
48 context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS` and |
|
49 ``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`. |
|
50 |
|
51 Configuring the message engine |
|
52 ============================== |
|
53 |
|
54 .. _message-storage-backends: |
|
55 |
|
56 Storage backends |
|
57 ---------------- |
|
58 |
|
59 The messages framework can use different backends to store temporary messages. |
|
60 To change which backend is being used, add a `MESSAGE_STORAGE`_ to your |
|
61 settings, referencing the module and class of the storage class. For |
|
62 example:: |
|
63 |
|
64 MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' |
|
65 |
|
66 The value should be the full path of the desired storage class. |
|
67 |
|
68 Four storage classes are included: |
|
69 |
|
70 ``'django.contrib.messages.storage.session.SessionStorage'`` |
|
71 This class stores all messages inside of the request's session. It |
|
72 requires Django's ``contrib.sessions`` application. |
|
73 |
|
74 ``'django.contrib.messages.storage.cookie.CookieStorage'`` |
|
75 This class stores the message data in a cookie (signed with a secret hash |
|
76 to prevent manipulation) to persist notifications across requests. Old |
|
77 messages are dropped if the cookie data size would exceed 4096 bytes. |
|
78 |
|
79 ``'django.contrib.messages.storage.fallback.FallbackStorage'`` |
|
80 This class first uses CookieStorage for all messages, falling back to using |
|
81 SessionStorage for the messages that could not fit in a single cookie. |
|
82 |
|
83 Since it is uses SessionStorage, it also requires Django's |
|
84 ``contrib.session`` application. |
|
85 |
|
86 ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` |
|
87 This is the default temporary storage class. |
|
88 |
|
89 This class extends FallbackStorage and adds compatibility methods to |
|
90 to retrieve any messages stored in the user Message model by code that |
|
91 has not yet been updated to use the new API. This storage is temporary |
|
92 (because it makes use of code that is pending deprecation) and will be |
|
93 removed in Django 1.4. At that time, the default storage will become |
|
94 ``django.contrib.messages.storage.fallback.FallbackStorage``. For more |
|
95 information, see `LegacyFallbackStorage`_ below. |
|
96 |
|
97 To write your own storage class, subclass the ``BaseStorage`` class in |
|
98 ``django.contrib.messages.storage.base`` and implement the ``_get`` and |
|
99 ``_store`` methods. |
|
100 |
|
101 LegacyFallbackStorage |
|
102 ^^^^^^^^^^^^^^^^^^^^^ |
|
103 |
|
104 The ``LegacyFallbackStorage`` is a temporary tool to facilitate the transition |
|
105 from the deprecated ``user.message_set`` API and will be removed in Django 1.4 |
|
106 according to Django's standard deprecation policy. For more information, see |
|
107 the full :doc:`release process documentation </internals/release-process>`. |
|
108 |
|
109 In addition to the functionality in the ``FallbackStorage``, it adds a custom, |
|
110 read-only storage class that retrieves messages from the user ``Message`` |
|
111 model. Any messages that were stored in the ``Message`` model (e.g., by code |
|
112 that has not yet been updated to use the messages framework) will be retrieved |
|
113 first, followed by those stored in a cookie and in the session, if any. Since |
|
114 messages stored in the ``Message`` model do not have a concept of levels, they |
|
115 will be assigned the ``INFO`` level by default. |
|
116 |
|
117 Message levels |
|
118 -------------- |
|
119 |
|
120 The messages framework is based on a configurable level architecture similar |
|
121 to that of the Python logging module. Message levels allow you to group |
|
122 messages by type so they can be filtered or displayed differently in views and |
|
123 templates. |
|
124 |
|
125 The built-in levels (which can be imported from ``django.contrib.messages`` |
|
126 directly) are: |
|
127 |
|
128 =========== ======== |
|
129 Constant Purpose |
|
130 =========== ======== |
|
131 ``DEBUG`` Development-related messages that will be ignored (or removed) in a production deployment |
|
132 ``INFO`` Informational messages for the user |
|
133 ``SUCCESS`` An action was successful, e.g. "Your profile was updated successfully" |
|
134 ``WARNING`` A failure did not occur but may be imminent |
|
135 ``ERROR`` An action was **not** successful or some other failure occurred |
|
136 =========== ======== |
|
137 |
|
138 The `MESSAGE_LEVEL`_ setting can be used to change the minimum recorded level |
|
139 (or it can be `changed per request`_). Attempts to add messages of a level less |
|
140 than this will be ignored. |
|
141 |
|
142 .. _`changed per request`: `Changing the minimum recorded level per-request`_ |
|
143 |
|
144 Message tags |
|
145 ------------ |
|
146 |
|
147 Message tags are a string representation of the message level plus any |
|
148 extra tags that were added directly in the view (see |
|
149 `Adding extra message tags`_ below for more details). Tags are stored in a |
|
150 string and are separated by spaces. Typically, message tags |
|
151 are used as CSS classes to customize message style based on message type. By |
|
152 default, each level has a single tag that's a lowercase version of its own |
|
153 constant: |
|
154 |
|
155 ============== =========== |
|
156 Level Constant Tag |
|
157 ============== =========== |
|
158 ``DEBUG`` ``debug`` |
|
159 ``INFO`` ``info`` |
|
160 ``SUCCESS`` ``success`` |
|
161 ``WARNING`` ``warning`` |
|
162 ``ERROR`` ``error`` |
|
163 ============== =========== |
|
164 |
|
165 To change the default tags for a message level (either built-in or custom), |
|
166 set the `MESSAGE_TAGS`_ setting to a dictionary containing the levels |
|
167 you wish to change. As this extends the default tags, you only need to provide |
|
168 tags for the levels you wish to override:: |
|
169 |
|
170 from django.contrib.messages import constants as messages |
|
171 MESSAGE_TAGS = { |
|
172 messages.INFO: '', |
|
173 50: 'critical', |
|
174 } |
|
175 |
|
176 Using messages in views and templates |
|
177 ===================================== |
|
178 |
|
179 Adding a message |
|
180 ---------------- |
|
181 |
|
182 To add a message, call:: |
|
183 |
|
184 from django.contrib import messages |
|
185 messages.add_message(request, messages.INFO, 'Hello world.') |
|
186 |
|
187 Some shortcut methods provide a standard way to add messages with commonly |
|
188 used tags (which are usually represented as HTML classes for the message):: |
|
189 |
|
190 messages.debug(request, '%s SQL statements were executed.' % count) |
|
191 messages.info(request, 'Three credits remain in your account.') |
|
192 messages.success(request, 'Profile details updated.') |
|
193 messages.warning(request, 'Your account expires in three days.') |
|
194 messages.error(request, 'Document deleted.') |
|
195 |
|
196 Displaying messages |
|
197 ------------------- |
|
198 |
|
199 In your template, use something like:: |
|
200 |
|
201 {% if messages %} |
|
202 <ul class="messages"> |
|
203 {% for message in messages %} |
|
204 <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> |
|
205 {% endfor %} |
|
206 </ul> |
|
207 {% endif %} |
|
208 |
|
209 If you're using the context processor, your template should be rendered with a |
|
210 ``RequestContext``. Otherwise, ensure ``messages`` is available to |
|
211 the template context. |
|
212 |
|
213 Creating custom message levels |
|
214 ------------------------------ |
|
215 |
|
216 Messages levels are nothing more than integers, so you can define your own |
|
217 level constants and use them to create more customized user feedback, e.g.:: |
|
218 |
|
219 CRITICAL = 50 |
|
220 |
|
221 def my_view(request): |
|
222 messages.add_message(request, CRITICAL, 'A serious error occurred.') |
|
223 |
|
224 When creating custom message levels you should be careful to avoid overloading |
|
225 existing levels. The values for the built-in levels are: |
|
226 |
|
227 .. _message-level-constants: |
|
228 |
|
229 ============== ===== |
|
230 Level Constant Value |
|
231 ============== ===== |
|
232 ``DEBUG`` 10 |
|
233 ``INFO`` 20 |
|
234 ``SUCCESS`` 25 |
|
235 ``WARNING`` 30 |
|
236 ``ERROR`` 40 |
|
237 ============== ===== |
|
238 |
|
239 If you need to identify the custom levels in your HTML or CSS, you need to |
|
240 provide a mapping via the `MESSAGE_TAGS`_ setting. |
|
241 |
|
242 .. note:: |
|
243 If you are creating a reusable application, it is recommended to use |
|
244 only the built-in `message levels`_ and not rely on any custom levels. |
|
245 |
|
246 Changing the minimum recorded level per-request |
|
247 ----------------------------------------------- |
|
248 |
|
249 The minimum recorded level can be set per request via the ``set_level`` |
|
250 method:: |
|
251 |
|
252 from django.contrib import messages |
|
253 |
|
254 # Change the messages level to ensure the debug message is added. |
|
255 messages.set_level(request, messages.DEBUG) |
|
256 messages.debug(request, 'Test message...') |
|
257 |
|
258 # In another request, record only messages with a level of WARNING and higher |
|
259 messages.set_level(request, messages.WARNING) |
|
260 messages.success(request, 'Your profile was updated.') # ignored |
|
261 messages.warning(request, 'Your account is about to expire.') # recorded |
|
262 |
|
263 # Set the messages level back to default. |
|
264 messages.set_level(request, None) |
|
265 |
|
266 Similarly, the current effective level can be retrieved with ``get_level``:: |
|
267 |
|
268 from django.contrib import messages |
|
269 current_level = messages.get_level(request) |
|
270 |
|
271 For more information on how the minimum recorded level functions, see |
|
272 `Message levels`_ above. |
|
273 |
|
274 Adding extra message tags |
|
275 ------------------------- |
|
276 |
|
277 For more direct control over message tags, you can optionally provide a string |
|
278 containing extra tags to any of the add methods:: |
|
279 |
|
280 messages.add_message(request, messages.INFO, 'Over 9000!', |
|
281 extra_tags='dragonball') |
|
282 messages.error(request, 'Email box full', extra_tags='email') |
|
283 |
|
284 Extra tags are added before the default tag for that level and are space |
|
285 separated. |
|
286 |
|
287 Failing silently when the message framework is disabled |
|
288 ------------------------------------------------------- |
|
289 |
|
290 If you're writing a reusable app (or other piece of code) and want to include |
|
291 messaging functionality, but don't want to require your users to enable it |
|
292 if they don't want to, you may pass an additional keyword argument |
|
293 ``fail_silently=True`` to any of the ``add_message`` family of methods. For |
|
294 example:: |
|
295 |
|
296 messages.add_message(request, messages.SUCCESS, 'Profile details updated.', |
|
297 fail_silently=True) |
|
298 messages.info(request, 'Hello world.', fail_silently=True) |
|
299 |
|
300 Internally, Django uses this functionality in the create, update, and delete |
|
301 :doc:`generic views </topics/http/generic-views>` so that they work even if the |
|
302 message framework is disabled. |
|
303 |
|
304 .. note:: |
|
305 Setting ``fail_silently=True`` only hides the ``MessageFailure`` that would |
|
306 otherwise occur when the messages framework disabled and one attempts to |
|
307 use one of the ``add_message`` family of methods. It does not hide failures |
|
308 that may occur for other reasons. |
|
309 |
|
310 Expiration of messages |
|
311 ====================== |
|
312 |
|
313 The messages are marked to be cleared when the storage instance is iterated |
|
314 (and cleared when the response is processed). |
|
315 |
|
316 To avoid the messages being cleared, you can set the messages storage to |
|
317 ``False`` after iterating:: |
|
318 |
|
319 storage = messages.get_messages(request) |
|
320 for message in storage: |
|
321 do_something_with(message) |
|
322 storage.used = False |
|
323 |
|
324 Behavior of parallel requests |
|
325 ============================= |
|
326 |
|
327 Due to the way cookies (and hence sessions) work, **the behavior of any |
|
328 backends that make use of cookies or sessions is undefined when the same |
|
329 client makes multiple requests that set or get messages in parallel**. For |
|
330 example, if a client initiates a request that creates a message in one window |
|
331 (or tab) and then another that fetches any uniterated messages in another |
|
332 window, before the first window redirects, the message may appear in the |
|
333 second window instead of the first window where it may be expected. |
|
334 |
|
335 In short, when multiple simultaneous requests from the same client are |
|
336 involved, messages are not guaranteed to be delivered to the same window that |
|
337 created them nor, in some cases, at all. Note that this is typically not a |
|
338 problem in most applications and will become a non-issue in HTML5, where each |
|
339 window/tab will have its own browsing context. |
|
340 |
|
341 Settings |
|
342 ======== |
|
343 |
|
344 A few :doc:`Django settings </ref/settings>` give you control over message |
|
345 behavior: |
|
346 |
|
347 MESSAGE_LEVEL |
|
348 ------------- |
|
349 |
|
350 Default: ``messages.INFO`` |
|
351 |
|
352 This sets the minimum message that will be saved in the message storage. See |
|
353 `Message levels`_ above for more details. |
|
354 |
|
355 .. admonition:: Important |
|
356 |
|
357 If you override ``MESSAGE_LEVEL`` in your settings file and rely on any of |
|
358 the built-in constants, you must import the constants module directly to |
|
359 avoid the potential for circular imports, e.g.:: |
|
360 |
|
361 from django.contrib.messages import constants as message_constants |
|
362 MESSAGE_LEVEL = message_constants.DEBUG |
|
363 |
|
364 If desired, you may specify the numeric values for the constants directly |
|
365 according to the values in the above :ref:`constants table |
|
366 <message-level-constants>`. |
|
367 |
|
368 MESSAGE_STORAGE |
|
369 --------------- |
|
370 |
|
371 Default: ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` |
|
372 |
|
373 Controls where Django stores message data. Valid values are: |
|
374 |
|
375 * ``'django.contrib.messages.storage.fallback.FallbackStorage'`` |
|
376 * ``'django.contrib.messages.storage.session.SessionStorage'`` |
|
377 * ``'django.contrib.messages.storage.cookie.CookieStorage'`` |
|
378 * ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` |
|
379 |
|
380 See `Storage backends`_ for more details. |
|
381 |
|
382 MESSAGE_TAGS |
|
383 ------------ |
|
384 |
|
385 Default:: |
|
386 |
|
387 {messages.DEBUG: 'debug', |
|
388 messages.INFO: 'info', |
|
389 messages.SUCCESS: 'success', |
|
390 messages.WARNING: 'warning', |
|
391 messages.ERROR: 'error',} |
|
392 |
|
393 This sets the mapping of message level to message tag, which is typically |
|
394 rendered as a CSS class in HTML. If you specify a value, it will extend |
|
395 the default. This means you only have to specify those values which you need |
|
396 to override. See `Displaying messages`_ above for more details. |
|
397 |
|
398 .. admonition:: Important |
|
399 |
|
400 If you override ``MESSAGE_TAGS`` in your settings file and rely on any of |
|
401 the built-in constants, you must import the ``constants`` module directly to |
|
402 avoid the potential for circular imports, e.g.:: |
|
403 |
|
404 from django.contrib.messages import constants as message_constants |
|
405 MESSAGE_TAGS = {message_constants.INFO: ''} |
|
406 |
|
407 If desired, you may specify the numeric values for the constants directly |
|
408 according to the values in the above :ref:`constants table |
|
409 <message-level-constants>`. |
|
410 |
|
411 .. _Django settings: ../settings/ |