mirror of
https://github.com/django/django.git
synced 2025-10-23 21:59:11 +00:00
[soc2009/multidb] Merged up to trunk r11804.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -171,6 +171,7 @@ Other batteries included
|
||||
* :ref:`Internationalization <topics-i18n>`
|
||||
* :ref:`Jython support <howto-jython>`
|
||||
* :ref:`"Local flavor" <ref-contrib-localflavor>`
|
||||
* :ref:`Messages <ref-contrib-messages>`
|
||||
* :ref:`Pagination <topics-pagination>`
|
||||
* :ref:`Redirects <ref-contrib-redirects>`
|
||||
* :ref:`Serialization <topics-serialization>`
|
||||
|
||||
@@ -426,6 +426,47 @@ translated, here's what to do:
|
||||
|
||||
.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
|
||||
|
||||
Django conventions
|
||||
==================
|
||||
|
||||
Various Django-specific code issues are detailed in this section.
|
||||
|
||||
Use of ``django.conf.settings``
|
||||
-------------------------------
|
||||
|
||||
Modules should not in general use settings stored in ``django.conf.settings`` at
|
||||
the top level (i.e. evaluated when the module is imported). The explanation for
|
||||
this is as follows:
|
||||
|
||||
Manual configuration of settings (i.e. not relying on the
|
||||
``DJANGO_SETTINGS_MODULE`` environment variable) is allowed and possible as
|
||||
follows::
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
settings.configure({}, SOME_SETTING='foo')
|
||||
|
||||
However, if any setting is accessed before the ``settings.configure`` line, this
|
||||
will not work. (Internally, ``setttings`` is a ``LazyObject`` which configures
|
||||
itself automatically when the settings are accessed if it has not already been
|
||||
configured).
|
||||
|
||||
So, if there is a module containg some code as follows::
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import get_callable
|
||||
|
||||
default_foo_view = get_callable(settings.FOO_VIEW)
|
||||
|
||||
...then importing this module will cause the settings object to be configured.
|
||||
That means that the ability for third parties to import the module at the top
|
||||
level is incompatible with the ability to configure the settings object
|
||||
manually, or makes it very difficult in some circumstances.
|
||||
|
||||
Instead of the above code, a level of laziness or indirection must be used, such
|
||||
as :class:`django.utils.functional.LazyObject`, :func:`django.utils.functional.lazy` or
|
||||
``lambda``.
|
||||
|
||||
Coding style
|
||||
============
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||
multiple databases. In 1.4, the support functions that allow methods
|
||||
with the old prototype to continue working will be removed.
|
||||
|
||||
* The ``Message`` model (in ``django.contrib.auth``), its related
|
||||
manager in the ``User`` model (``user.message_set``), and the
|
||||
associated methods (``user.message_set.create()`` and
|
||||
``user.get_and_delete_messages()``), which have
|
||||
been deprecated since the 1.2 release, will be removed. The
|
||||
:ref:`messages framework <ref-contrib-messages>` should be used
|
||||
instead.
|
||||
|
||||
* 2.0
|
||||
* ``django.views.defaults.shortcut()``. This function has been moved
|
||||
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
|
||||
|
||||
@@ -153,6 +153,8 @@ launch a CSRF attack on your site against that user. The
|
||||
``@csrf_response_exempt`` decorator can be used to fix this, but only if the
|
||||
page doesn't also contain internal forms that require the token.
|
||||
|
||||
.. _ref-csrf-upgrading-notes:
|
||||
|
||||
Upgrading notes
|
||||
---------------
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ those packages have.
|
||||
formtools/index
|
||||
humanize
|
||||
localflavor
|
||||
messages
|
||||
redirects
|
||||
sitemaps
|
||||
sites
|
||||
@@ -150,6 +151,17 @@ read the source code in django/contrib/markup/templatetags/markup.py.
|
||||
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
|
||||
.. _ReST (ReStructured Text): http://en.wikipedia.org/wiki/ReStructuredText
|
||||
|
||||
messages
|
||||
========
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
The messages framework was added.
|
||||
|
||||
A framework for storing and retrieving temporary cookie- or session-based
|
||||
messages
|
||||
|
||||
See the :ref:`messages documentation <ref-contrib-messages>`.
|
||||
|
||||
redirects
|
||||
=========
|
||||
|
||||
|
||||
405
docs/ref/contrib/messages.txt
Normal file
405
docs/ref/contrib/messages.txt
Normal file
@@ -0,0 +1,405 @@
|
||||
.. _ref-contrib-messages:
|
||||
|
||||
======================
|
||||
The messages framework
|
||||
======================
|
||||
|
||||
.. module:: django.contrib.messages
|
||||
:synopsis: Provides cookie- and session-based temporary message storage.
|
||||
|
||||
Django provides full support for cookie- and session-based messaging, for
|
||||
both anonymous and authenticated clients. The messages framework allows you
|
||||
to temporarily store messages in one request and retrieve them for display
|
||||
in a subsequent request (usually the next one). Every message is tagged
|
||||
with a specific ``level`` that determines its priority (e.g., ``info``,
|
||||
``warning``, or ``error``).
|
||||
|
||||
.. versionadded:: 1.2
|
||||
The messages framework was added.
|
||||
|
||||
Enabling messages
|
||||
=================
|
||||
|
||||
Messages are implemented through a :ref:`middleware <ref-middleware>`
|
||||
class and corresponding :ref:`context processor <ref-templates-api>`.
|
||||
|
||||
To enable message functionality, do the following:
|
||||
|
||||
* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
|
||||
it contains ``'django.contrib.messages.middleware.MessageMiddleware'``.
|
||||
|
||||
If you are using a :ref:`storage backend <message-storage-backends>` that
|
||||
relies on :ref:`sessions <topics-http-sessions>` (the default),
|
||||
``'django.contrib.sessions.middleware.SessionMiddleware'`` must be
|
||||
enabled and appear before ``MessageMiddleware`` in your
|
||||
:setting:`MIDDLEWARE_CLASSES`.
|
||||
|
||||
* Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure
|
||||
it contains ``'django.contrib.messages.context_processors.messages'``.
|
||||
|
||||
* Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS`
|
||||
setting
|
||||
|
||||
The default ``settings.py`` created by ``django-admin.py startproject`` has
|
||||
``MessageMiddleware`` activated and the ``django.contrib.messages`` app
|
||||
installed. Also, the default value for :setting:`TEMPLATE_CONTEXT_PROCESSORS`
|
||||
contains ``'django.contrib.messages.context_processors.messages'``.
|
||||
|
||||
If you don't want to use messages, you can remove the
|
||||
``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, the ``messages``
|
||||
context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS` and
|
||||
``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`.
|
||||
|
||||
Configuring the message engine
|
||||
==============================
|
||||
|
||||
.. _message-storage-backends:
|
||||
|
||||
Storage backends
|
||||
----------------
|
||||
|
||||
The messages framework can use different backends to store temporary messages.
|
||||
To change which backend is being used, add a `MESSAGE_STORAGE`_ to your
|
||||
settings, referencing the module and class of the storage class. For
|
||||
example::
|
||||
|
||||
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
|
||||
|
||||
The value should be the full path of the desired storage class.
|
||||
|
||||
Four storage classes are included:
|
||||
|
||||
``'django.contrib.messages.storage.session.SessionStorage'``
|
||||
This class stores all messages inside of the request's session. It
|
||||
requires Django's ``contrib.session`` application.
|
||||
|
||||
``'django.contrib.messages.storage.cookie.CookieStorage'``
|
||||
This class stores the message data in a cookie (signed with a secret hash
|
||||
to prevent manipulation) to persist notifications across requests. Old
|
||||
messages are dropped if the cookie data size would exceed 4096 bytes.
|
||||
|
||||
``'django.contrib.messages.storage.fallback.FallbackStorage'``
|
||||
This class first uses CookieStorage for all messages, falling back to using
|
||||
SessionStorage for the messages that could not fit in a single cookie.
|
||||
|
||||
Since it is uses SessionStorage, it also requires Django's
|
||||
``contrib.session`` application.
|
||||
|
||||
``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'``
|
||||
This is the default temporary storage class.
|
||||
|
||||
This class extends FallbackStorage and adds compatibility methods to
|
||||
to retrieve any messages stored in the user Message model by code that
|
||||
has not yet been updated to use the new API. This storage is temporary
|
||||
(because it makes use of code that is pending deprecation) and will be
|
||||
removed in Django 1.4. At that time, the default storage will become
|
||||
``django.contrib.messages.storage.fallback.FallbackStorage``. For more
|
||||
information, see `LegacyFallbackStorage`_ below.
|
||||
|
||||
To write your own storage class, subclass the ``BaseStorage`` class in
|
||||
``django.contrib.messages.storage.base`` and implement the ``_get`` and
|
||||
``_store`` methods.
|
||||
|
||||
LegacyFallbackStorage
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``LegacyFallbackStorage`` is a temporary tool to facilitate the transition
|
||||
from the deprecated ``user.message_set`` API and will be removed in Django 1.4
|
||||
according to Django's standard deprecation policy. For more information, see
|
||||
the full :ref:`release process documentation <internals-release-process>`.
|
||||
|
||||
In addition to the functionality in the ``FallbackStorage``, it adds a custom,
|
||||
read-only storage class that retrieves messages from the user ``Message``
|
||||
model. Any messages that were stored in the ``Message`` model (e.g., by code
|
||||
that has not yet been updated to use the messages framework) will be retrieved
|
||||
first, followed by those stored in a cookie and in the session, if any. Since
|
||||
messages stored in the ``Message`` model do not have a concept of levels, they
|
||||
will be assigned the ``INFO`` level by default.
|
||||
|
||||
Message levels
|
||||
--------------
|
||||
|
||||
The messages framework is based on a configurable level architecture similar
|
||||
to that of the Python logging module. Message levels allow you to group
|
||||
messages by type so they can be filtered or displayed differently in views and
|
||||
templates.
|
||||
|
||||
The built-in levels (which can be imported from ``django.contrib.messages``
|
||||
directly) are:
|
||||
|
||||
=========== ========
|
||||
Constant Purpose
|
||||
=========== ========
|
||||
``DEBUG`` Development-related messages that will be ignored (or removed) in a production deployment
|
||||
``INFO`` Informational messages for the user
|
||||
``SUCCESS`` An action was successful, e.g. "Your profile was updated successfully"
|
||||
``WARNING`` A failure did not occur but may be imminent
|
||||
``ERROR`` An action was **not** successful or some other failure occurred
|
||||
=========== ========
|
||||
|
||||
The `MESSAGE_LEVEL`_ setting can be used to change the minimum recorded
|
||||
level. Attempts to add messages of a level less than this will be ignored.
|
||||
|
||||
Message tags
|
||||
------------
|
||||
|
||||
Message tags are a string representation of the message level plus any
|
||||
extra tags that were added directly in the view (see
|
||||
`Adding extra message tags`_ below for more details). Tags are stored in a
|
||||
string and are separated by spaces. Typically, message tags
|
||||
are used as CSS classes to customize message style based on message type. By
|
||||
default, each level has a single tag that's a lowercase version of its own
|
||||
constant:
|
||||
|
||||
============== ===========
|
||||
Level Constant Tag
|
||||
============== ===========
|
||||
``DEBUG`` ``debug``
|
||||
``INFO`` ``info``
|
||||
``SUCCESS`` ``success``
|
||||
``WARNING`` ``warning``
|
||||
``ERROR`` ``error``
|
||||
============== ===========
|
||||
|
||||
To change the default tags for a message level (either built-in or custom),
|
||||
set the `MESSAGE_TAGS`_ setting to a dictionary containing the levels
|
||||
you wish to change. As this extends the default tags, you only need to provide
|
||||
tags for the levels you wish to override::
|
||||
|
||||
from django.contrib.messages import constants as messages
|
||||
MESSAGE_TAGS = {
|
||||
messages.INFO: '',
|
||||
50: 'critical',
|
||||
}
|
||||
|
||||
Using messages in views and templates
|
||||
=====================================
|
||||
|
||||
Adding a message
|
||||
----------------
|
||||
|
||||
To add a message, call::
|
||||
|
||||
from django.contrib import messages
|
||||
messages.add_message(request, messages.INFO, 'Hello world.')
|
||||
|
||||
Some shortcut methods provide a standard way to add messages with commonly
|
||||
used tags (which are usually represented as HTML classes for the message)::
|
||||
|
||||
messages.debug(request, '%s SQL statements were executed.' % count)
|
||||
messages.info(request, 'Three credits remain in your account.')
|
||||
messages.success(request, 'Profile details updated.')
|
||||
messages.warning(request, 'Your account expires in three days.')
|
||||
messages.error(request, 'Document deleted.')
|
||||
|
||||
Displaying messages
|
||||
-------------------
|
||||
|
||||
In your template, use something like::
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
If you're using the context processor, your template should be rendered with a
|
||||
``RequestContext``. Otherwise, ensure ``messages`` is available to
|
||||
the template context.
|
||||
|
||||
Creating custom message levels
|
||||
------------------------------
|
||||
|
||||
Messages levels are nothing more than integers, so you can define your own
|
||||
level constants and use them to create more customized user feedback, e.g.::
|
||||
|
||||
CRITICAL = 50
|
||||
|
||||
def my_view(request):
|
||||
messages.add_message(request, CRITICAL, 'A serious error occurred.')
|
||||
|
||||
When creating custom message levels you should be careful to avoid overloading
|
||||
existing levels. The values for the built-in levels are:
|
||||
|
||||
.. _message-level-constants:
|
||||
|
||||
============== =====
|
||||
Level Constant Value
|
||||
============== =====
|
||||
``DEBUG`` 10
|
||||
``INFO`` 20
|
||||
``SUCCESS`` 25
|
||||
``WARNING`` 30
|
||||
``ERROR`` 40
|
||||
============== =====
|
||||
|
||||
If you need to identify the custom levels in your HTML or CSS, you need to
|
||||
provide a mapping via the `MESSAGE_TAGS`_ setting.
|
||||
|
||||
.. note::
|
||||
If you are creating a reusable application, it is recommended to use
|
||||
only the built-in `message levels`_ and not rely on any custom levels.
|
||||
|
||||
Changing the minimum recorded level per-request
|
||||
-----------------------------------------------
|
||||
|
||||
The minimum recorded level can be set per request by changing the ``level``
|
||||
attribute of the messages storage instance::
|
||||
|
||||
from django.contrib import messages
|
||||
|
||||
# Change the messages level to ensure the debug message is added.
|
||||
messages.get_messages(request).level = messages.DEBUG
|
||||
messages.debug(request, 'Test message...')
|
||||
|
||||
# In another request, record only messages with a level of WARNING and higher
|
||||
messages.get_messages(request).level = messages.WARNING
|
||||
messages.success(request, 'Your profile was updated.') # ignored
|
||||
messages.warning(request, 'Your account is about to expire.') # recorded
|
||||
|
||||
# Set the messages level back to default.
|
||||
messages.get_messages(request).level = None
|
||||
|
||||
For more information on how the minimum recorded level functions, see
|
||||
`Message levels`_ above.
|
||||
|
||||
Adding extra message tags
|
||||
-------------------------
|
||||
|
||||
For more direct control over message tags, you can optionally provide a string
|
||||
containing extra tags to any of the add methods::
|
||||
|
||||
messages.add_message(request, messages.INFO, 'Over 9000!',
|
||||
extra_tags='dragonball')
|
||||
messages.error(request, 'Email box full', extra_tags='email')
|
||||
|
||||
Extra tags are added before the default tag for that level and are space
|
||||
separated.
|
||||
|
||||
Failing silently when the message framework is disabled
|
||||
-------------------------------------------------------
|
||||
|
||||
If you're writing a reusable app (or other piece of code) and want to include
|
||||
messaging functionality, but don't want to require your users to enable it
|
||||
if they don't want to, you may pass an additional keyword argument
|
||||
``fail_silently=True`` to any of the ``add_message`` family of methods. For
|
||||
example::
|
||||
|
||||
messages.add_message(request, messages.SUCCESS, 'Profile details updated.',
|
||||
fail_silently=True)
|
||||
messages.info(request, 'Hello world.', fail_silently=True)
|
||||
|
||||
Internally, Django uses this functionality in the create, update, and delete
|
||||
:ref:`generic views <topics-generic-views>` so that they work even if the
|
||||
message framework is disabled.
|
||||
|
||||
.. note::
|
||||
Setting ``fail_silently=True`` only hides the ``MessageFailure`` that would
|
||||
otherwise occur when the messages framework disabled and one attempts to
|
||||
use one of the ``add_message`` family of methods. It does not hide failures
|
||||
that may occur for other reasons.
|
||||
|
||||
Expiration of messages
|
||||
======================
|
||||
|
||||
The messages are marked to be cleared when the storage instance is iterated
|
||||
(and cleared when the response is processed).
|
||||
|
||||
To avoid the messages being cleared, you can set the messages storage to
|
||||
``False`` after iterating::
|
||||
|
||||
storage = messages.get_messages(request)
|
||||
for message in storage:
|
||||
do_something_with(message)
|
||||
storage.used = False
|
||||
|
||||
Behavior of parallel requests
|
||||
=============================
|
||||
|
||||
Due to the way cookies (and hence sessions) work, **the behavior of any
|
||||
backends that make use of cookies or sessions is undefined when the same
|
||||
client makes multiple requests that set or get messages in parallel**. For
|
||||
example, if a client initiates a request that creates a message in one window
|
||||
(or tab) and then another that fetches any uniterated messages in another
|
||||
window, before the first window redirects, the message may appear in the
|
||||
second window instead of the first window where it may be expected.
|
||||
|
||||
In short, when multiple simultaneous requests from the same client are
|
||||
involved, messages are not guaranteed to be delivered to the same window that
|
||||
created them nor, in some cases, at all. Note that this is typically not a
|
||||
problem in most applications and will become a non-issue in HTML5, where each
|
||||
window/tab will have its own browsing context.
|
||||
|
||||
Settings
|
||||
========
|
||||
|
||||
A few :ref:`Django settings <ref-settings>` give you control over message
|
||||
behavior:
|
||||
|
||||
MESSAGE_LEVEL
|
||||
-------------
|
||||
|
||||
Default: ``messages.INFO``
|
||||
|
||||
This sets the minimum message that will be saved in the message storage. See
|
||||
`Message levels`_ above for more details.
|
||||
|
||||
.. admonition:: Important
|
||||
|
||||
If you override ``MESSAGE_LEVEL`` in your settings file and rely on any of
|
||||
the built-in constants, you must import the constants module directly to
|
||||
avoid the potential for circular imports, e.g.::
|
||||
|
||||
from django.contrib.messages import constants as message_constants
|
||||
MESSAGE_LEVEL = message_constants.DEBUG
|
||||
|
||||
If desired, you may specify the numeric values for the constants directly
|
||||
according to the values in the above :ref:`constants table
|
||||
<message-level-constants>`.
|
||||
|
||||
MESSAGE_STORAGE
|
||||
---------------
|
||||
|
||||
Default: ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'``
|
||||
|
||||
Controls where Django stores message data. Valid values are:
|
||||
|
||||
* ``'django.contrib.messages.storage.fallback.FallbackStorage'``
|
||||
* ``'django.contrib.messages.storage.session.SessionStorage'``
|
||||
* ``'django.contrib.messages.storage.cookie.CookieStorage'``
|
||||
* ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'``
|
||||
|
||||
See `Storage backends`_ for more details.
|
||||
|
||||
MESSAGE_TAGS
|
||||
------------
|
||||
|
||||
Default::
|
||||
|
||||
{messages.DEBUG: 'debug',
|
||||
messages.INFO: 'info',
|
||||
messages.SUCCESS: 'success',
|
||||
messages.WARNING: 'warning',
|
||||
messages.ERROR: 'error',}
|
||||
|
||||
This sets the mapping of message level to message tag, which is typically
|
||||
rendered as a CSS class in HTML. If you specify a value, it will extend
|
||||
the default. This means you only have to specify those values which you need
|
||||
to override. See `Displaying messages`_ above for more details.
|
||||
|
||||
.. admonition:: Important
|
||||
|
||||
If you override ``MESSAGE_TAGS`` in your settings file and rely on any of
|
||||
the built-in constants, you must import the ``constants`` module directly to
|
||||
avoid the potential for circular imports, e.g.::
|
||||
|
||||
from django.contrib.messages import constants as message_constants
|
||||
MESSAGE_TAGS = {message_constants.INFO: ''}
|
||||
|
||||
If desired, you may specify the numeric values for the constants directly
|
||||
according to the values in the above :ref:`constants table
|
||||
<message-level-constants>`.
|
||||
|
||||
.. _Django settings: ../settings/
|
||||
@@ -139,6 +139,20 @@ Enables language selection based on data from the request. It customizes
|
||||
content for each user. See the :ref:`internationalization documentation
|
||||
<topics-i18n>`.
|
||||
|
||||
Message middleware
|
||||
------------------
|
||||
|
||||
.. module:: django.contrib.messages.middleware
|
||||
:synopsis: Message middleware.
|
||||
|
||||
.. class:: django.contrib.messages.middleware.MessageMiddleware
|
||||
|
||||
.. versionadded:: 1.2
|
||||
``MessageMiddleware`` was added.
|
||||
|
||||
Enables cookie- and session-based message support. See the
|
||||
:ref:`messages documentation <ref-contrib-messages>`.
|
||||
|
||||
Session middleware
|
||||
------------------
|
||||
|
||||
|
||||
@@ -896,6 +896,43 @@ Bad: ``"http://www.example.com/static"``
|
||||
|
||||
.. setting:: MIDDLEWARE_CLASSES
|
||||
|
||||
MESSAGE_LEVEL
|
||||
-------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default: `messages.INFO`
|
||||
|
||||
Sets the minimum message level that will be recorded by the messages
|
||||
framework. See the :ref:`messages documentation <ref-contrib-messages>` for
|
||||
more details.
|
||||
|
||||
MESSAGE_STORAGE
|
||||
---------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default: ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'``
|
||||
|
||||
Controls where Django stores message data. See the
|
||||
:ref:`messages documentation <ref-contrib-messages>` for more details.
|
||||
|
||||
MESSAGE_TAGS
|
||||
------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default::
|
||||
|
||||
{messages.DEBUG: 'debug',
|
||||
messages.INFO: 'info',
|
||||
messages.SUCCESS: 'success',
|
||||
messages.WARNING: 'warning',
|
||||
messages.ERROR: 'error',}
|
||||
|
||||
Sets the mapping of message levels to message tags. See the
|
||||
:ref:`messages documentation <ref-contrib-messages>` for more details.
|
||||
|
||||
MIDDLEWARE_CLASSES
|
||||
------------------
|
||||
|
||||
@@ -904,10 +941,16 @@ Default::
|
||||
('django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',)
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',)
|
||||
|
||||
A tuple of middleware classes to use. See :ref:`topics-http-middleware`.
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
``'django.contrib.messages.middleware.MessageMiddleware'`` was added to the
|
||||
default. For more information, see the :ref:`messages documentation
|
||||
<ref-contrib-messages>`.
|
||||
|
||||
.. setting:: MONTH_DAY_FORMAT
|
||||
|
||||
MONTH_DAY_FORMAT
|
||||
@@ -1155,12 +1198,18 @@ Default::
|
||||
("django.core.context_processors.auth",
|
||||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n",
|
||||
"django.core.context_processors.media")
|
||||
"django.core.context_processors.media",
|
||||
"django.contrib.messages.context_processors.messages")
|
||||
|
||||
A tuple of callables that are used to populate the context in ``RequestContext``.
|
||||
These callables take a request object as their argument and return a dictionary
|
||||
of items to be merged into the context.
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
``"django.contrib.messages.context_processors.messages"`` was added to the
|
||||
default. For more information, see the :ref:`messages documentation
|
||||
<ref-contrib-messages>`.
|
||||
|
||||
.. setting:: TEMPLATE_DEBUG
|
||||
|
||||
TEMPLATE_DEBUG
|
||||
|
||||
@@ -311,7 +311,8 @@ and return a dictionary of items to be merged into the context. By default,
|
||||
("django.core.context_processors.auth",
|
||||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n",
|
||||
"django.core.context_processors.media")
|
||||
"django.core.context_processors.media",
|
||||
"django.contrib.messages.context_processors.messages")
|
||||
|
||||
.. versionadded:: 1.2
|
||||
In addition to these, ``RequestContext`` always uses
|
||||
@@ -320,6 +321,10 @@ and return a dictionary of items to be merged into the context. By default,
|
||||
in case of accidental misconfiguration, it is deliberately hardcoded in and
|
||||
cannot be turned off by the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
The ``'messages'`` context processor was added. For more information, see
|
||||
the :ref:`messages documentation <ref-contrib-messages>`.
|
||||
|
||||
Each processor is applied in order. That means, if one processor adds a
|
||||
variable to the context and a second processor adds a variable with the same
|
||||
name, the second will override the first. The default processors are explained
|
||||
@@ -365,17 +370,18 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
|
||||
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
|
||||
logged in).
|
||||
|
||||
* ``messages`` -- A list of messages (as strings) for the currently
|
||||
logged-in user. Behind the scenes, this calls
|
||||
``request.user.get_and_delete_messages()`` for every request. That method
|
||||
collects the user's messages and deletes them from the database.
|
||||
|
||||
Note that messages are set with ``user.message_set.create``.
|
||||
* ``messages`` -- A list of messages (as strings) that have been set
|
||||
via the :ref:`messages framework <ref-contrib-messages>`.
|
||||
|
||||
* ``perms`` -- An instance of
|
||||
``django.core.context_processors.PermWrapper``, representing the
|
||||
permissions that the currently logged-in user has.
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
Prior to version 1.2, the ``messages`` variable was a lazy accessor for
|
||||
``user.get_and_delete_messages()``. It has been changed to include any
|
||||
messages added via the :ref:`messages framework <ref-contrib-messages`.
|
||||
|
||||
django.core.context_processors.debug
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -427,6 +433,25 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
|
||||
:class:`~django.http.HttpRequest`. Note that this processor is not enabled by default;
|
||||
you'll have to activate it.
|
||||
|
||||
django.contrib.messages.context_processors.messages
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
|
||||
``RequestContext`` will contain a single additional variable:
|
||||
|
||||
* ``messages`` -- A list of messages (as strings) that have been set
|
||||
via the user model (using ``user.message_set.create``) or through
|
||||
the :ref:`messages framework <ref-contrib-messages>`.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
This template context variable was previously supplied by the ``'auth'``
|
||||
context processor. For backwards compatibility the ``'auth'`` context
|
||||
processor will continue to supply the ``messages`` variable until Django
|
||||
1.4. If you use the ``messages`` variable, your project will work with
|
||||
either (or both) context processors, but it is recommended to add
|
||||
``django.contrib.messages.context_processors.messages`` so your project
|
||||
will be prepared for the future upgrade.
|
||||
|
||||
Writing your own context processors
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ There have been large changes to the way that CSRF protection works, detailed in
|
||||
changes that developers must be aware of:
|
||||
|
||||
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and
|
||||
will be removed completely in Django 1.4, in favour of a template tag that
|
||||
will be removed completely in Django 1.4, in favor of a template tag that
|
||||
should be inserted into forms.
|
||||
|
||||
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This
|
||||
requires the use of the csrf_token template tag in the template, so if you
|
||||
have used custom templates for contrib views, you MUST READ THE UPGRADE
|
||||
INSTRUCTIONS to fix those templates.
|
||||
have used custom templates for contrib views, you MUST READ THE :ref:`UPGRADE
|
||||
INSTRUCTIONS <ref-csrf-upgrading-notes>` to fix those templates.
|
||||
|
||||
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
|
||||
default. This turns on CSRF protection by default, so that views that accept
|
||||
@@ -42,8 +42,8 @@ changes that developers must be aware of:
|
||||
* All of the CSRF has moved from contrib to core (with backwards compatible
|
||||
imports in the old locations, which are deprecated).
|
||||
|
||||
LazyObject
|
||||
----------
|
||||
``LazyObject``
|
||||
--------------
|
||||
|
||||
``LazyObject`` is an undocumented utility class used for lazily wrapping other
|
||||
objects of unknown type. In Django 1.1 and earlier, it handled introspection in
|
||||
@@ -214,7 +214,86 @@ argument to resolve database-specific values.
|
||||
Features deprecated in 1.2
|
||||
==========================
|
||||
|
||||
None.
|
||||
CSRF response rewriting middleware
|
||||
----------------------------------
|
||||
|
||||
``CsrfResponseMiddleware``, the middleware that automatically inserted CSRF
|
||||
tokens into POST forms in outgoing pages, has been deprecated in favor of a
|
||||
template tag method (see above), and will be removed completely in Django
|
||||
1.4. ``CsrfMiddleware``, which includes the functionality of
|
||||
``CsrfResponseMiddleware`` and ``CsrfViewMiddleware`` has likewise been
|
||||
deprecated.
|
||||
|
||||
Also, the CSRF module has moved from contrib to core, and the old imports are
|
||||
deprecated, as described in the :ref:`upgrading notes <ref-csrf-upgrading-notes>`.
|
||||
|
||||
``SMTPConnection``
|
||||
------------------
|
||||
|
||||
The ``SMTPConnection`` class has been deprecated in favor of a generic
|
||||
E-mail backend API. Old code that explicitly instantiated an instance
|
||||
of an SMTPConnection::
|
||||
|
||||
from django.core.mail import SMTPConnection
|
||||
connection = SMTPConnection()
|
||||
messages = get_notification_email()
|
||||
connection.send_messages(messages)
|
||||
|
||||
should now call :meth:`~django.core.mail.get_connection()` to
|
||||
instantiate a generic e-mail connection::
|
||||
|
||||
from django.core.mail import get_connection
|
||||
connection = get_connection()
|
||||
messages = get_notification_email()
|
||||
connection.send_messages(messages)
|
||||
|
||||
Depending on the value of the :setting:`EMAIL_BACKEND` setting, this
|
||||
may not return an SMTP connection. If you explicitly require an SMTP
|
||||
connection with which to send e-mail, you can explicitly request an
|
||||
SMTP connection::
|
||||
|
||||
from django.core.mail import get_connection
|
||||
connection = get_connection('django.core.mail.backends.smtp')
|
||||
messages = get_notification_email()
|
||||
connection.send_messages(messages)
|
||||
|
||||
If your call to construct an instance of ``SMTPConnection`` required
|
||||
additional arguments, those arguments can be passed to the
|
||||
:meth:`~django.core.mail.get_connection()` call::
|
||||
|
||||
connection = get_connection('django.core.mail.backends.smtp', hostname='localhost', port=1234)
|
||||
|
||||
User Messages API
|
||||
-----------------
|
||||
|
||||
The API for storing messages in the user ``Message`` model (via
|
||||
``user.message_set.create``) is now deprecated and will be removed in Django
|
||||
1.4 according to the standard :ref:`release process <internals-release-process>`.
|
||||
|
||||
To upgrade your code, you need to replace any instances of::
|
||||
|
||||
user.message_set.create('a message')
|
||||
|
||||
with the following::
|
||||
|
||||
from django.contrib import messages
|
||||
messages.add_message(request, messages.INFO, 'a message')
|
||||
|
||||
Additionally, if you make use of the method, you need to replace the
|
||||
following::
|
||||
|
||||
for message in user.get_and_delete_messages():
|
||||
...
|
||||
|
||||
with::
|
||||
|
||||
from django.contrib import messages
|
||||
for message in messages.get_messages(request):
|
||||
...
|
||||
|
||||
For more information, see the full
|
||||
:ref:`messages documentation <ref-contrib-messages>`. You should begin to
|
||||
update your code to use the new API immediately.
|
||||
|
||||
What's new in Django 1.2
|
||||
========================
|
||||
@@ -231,23 +310,33 @@ malicious site in their browser. A related type of attack, 'login
|
||||
CSRF', where an attacking site tricks a user's browser into logging
|
||||
into a site with someone else's credentials, is also covered.
|
||||
|
||||
Email Backends
|
||||
--------------
|
||||
E-mail Backends
|
||||
---------------
|
||||
|
||||
You can now :ref:`configure the way that Django sends email
|
||||
<topic-email-backends>`. Instead of using SMTP to send all email, you
|
||||
can now choose a configurable email backend to send messages. If your
|
||||
You can now :ref:`configure the way that Django sends e-mail
|
||||
<topic-email-backends>`. Instead of using SMTP to send all e-mail, you
|
||||
can now choose a configurable e-mail backend to send messages. If your
|
||||
hosting provider uses a sandbox or some other non-SMTP technique for
|
||||
sending mail, you can now construct an email backend that will allow
|
||||
sending mail, you can now construct an e-mail backend that will allow
|
||||
Django's standard :ref:`mail sending methods<topics-email>` to use
|
||||
those facilities.
|
||||
|
||||
This also makes it easier to debug mail sending - Django ships with
|
||||
backend implementations that allow you to send email to a
|
||||
backend implementations that allow you to send e-mail to a
|
||||
:ref:`file<topic-email-file-backend>`, to the
|
||||
:ref:`console<topic-email-console-backend>`, or to
|
||||
:ref:`memory<topic-email-memory-backend>` - you can even configure all
|
||||
email to be :ref:`thrown away<topic-email-console-backend>`.
|
||||
e-mail to be :ref:`thrown away<topic-email-dummy-backend>`.
|
||||
|
||||
Messages Framework
|
||||
------------------
|
||||
|
||||
Django now includes a robust and configurable :ref:`messages framework
|
||||
<ref-contrib-messages>` with built-in support for cookie- and session-based
|
||||
messaging, for both anonymous and authenticated clients. The messages framework
|
||||
replaces the deprecated user message API and allows you to temporarily store
|
||||
messages in one request and retrieve them for display in a subsequent request
|
||||
(usually the next one).
|
||||
|
||||
Support for multiple databases
|
||||
------------------------------
|
||||
|
||||
@@ -23,6 +23,9 @@ The auth system consists of:
|
||||
user.
|
||||
* Messages: A simple way to queue messages for given users.
|
||||
|
||||
.. deprecated:: 1.2
|
||||
The Messages component of the auth system will be removed in Django 1.4.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
@@ -1289,6 +1292,11 @@ messages.
|
||||
Messages
|
||||
========
|
||||
|
||||
.. deprecated:: 1.2
|
||||
This functionality will be removed in Django 1.4. You should use the
|
||||
:ref:`messages framework <ref-contrib-messages>` for all new projects and
|
||||
begin to update your existing code immediately.
|
||||
|
||||
The message system is a lightweight way to queue messages for given users.
|
||||
|
||||
A message is associated with a :class:`~django.contrib.auth.models.User`.
|
||||
@@ -1334,13 +1342,16 @@ logged-in user and his/her messages are made available in the
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
Note that :class:`~django.template.context.RequestContext` calls
|
||||
:meth:`~django.contrib.auth.models.User.get_and_delete_messages` behind the
|
||||
scenes, so any messages will be deleted even if you don't display them.
|
||||
.. versionchanged:: 1.2
|
||||
The ``messages`` template variable uses a backwards compatible method in the
|
||||
:ref:`messages framework <ref-contrib-messages>` to retrieve messages from
|
||||
both the user ``Message`` model and from the new framework. Unlike in
|
||||
previous revisions, the messages will not be erased unless they are actually
|
||||
displayed.
|
||||
|
||||
Finally, note that this messages framework only works with users in the user
|
||||
database. To send messages to anonymous users, use the
|
||||
:ref:`session framework <topics-http-sessions>`.
|
||||
:ref:`messages framework <ref-contrib-messages>`.
|
||||
|
||||
.. _authentication-backends:
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Sending e-mail
|
||||
Although Python makes sending e-mail relatively easy via the `smtplib
|
||||
library`_, Django provides a couple of light wrappers over it. These wrappers
|
||||
are provided to make sending e-mail extra quick, to make it easy to test
|
||||
email sending during development, and to provide support for platforms that
|
||||
e-mail sending during development, and to provide support for platforms that
|
||||
can't use SMTP.
|
||||
|
||||
The code lives in the ``django.core.mail`` module.
|
||||
@@ -64,7 +64,7 @@ are required.
|
||||
* ``auth_password``: The optional password to use to authenticate to the
|
||||
SMTP server. If this isn't provided, Django will use the value of the
|
||||
``EMAIL_HOST_PASSWORD`` setting.
|
||||
* ``connection``: The optional email backend to use to send the mail.
|
||||
* ``connection``: The optional e-mail backend to use to send the mail.
|
||||
If unspecified, an instance of the default backend will be used.
|
||||
See the documentation on :ref:`E-mail backends <topic-email-backends>`
|
||||
for more details.
|
||||
@@ -215,8 +215,8 @@ message itself. The :ref:`e-mail backend <topic-email-backends>` is then
|
||||
responsible for sending the e-mail.
|
||||
|
||||
For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
|
||||
``send()`` method for sending a single email. If you need to send multiple
|
||||
messages, the email backend API :ref:`provides an alternative
|
||||
``send()`` method for sending a single e-mail. If you need to send multiple
|
||||
messages, the e-mail backend API :ref:`provides an alternative
|
||||
<topics-sending-multiple-emails>`.
|
||||
|
||||
EmailMessage Objects
|
||||
@@ -264,7 +264,7 @@ For example::
|
||||
The class has the following methods:
|
||||
|
||||
* ``send(fail_silently=False)`` sends the message. If a connection was
|
||||
specified when the email was constructed, that connection will be used.
|
||||
specified when the e-mail was constructed, that connection will be used.
|
||||
Otherwise, an instance of the default backend will be instantiated and
|
||||
used. If the keyword argument ``fail_silently`` is ``True``, exceptions
|
||||
raised while sending the message will be quashed.
|
||||
@@ -358,9 +358,9 @@ The actual sending of an e-mail is handled by the e-mail backend.
|
||||
|
||||
The e-mail backend class has the following methods:
|
||||
|
||||
* ``open()`` instantiates an long-lived email-sending connection.
|
||||
* ``open()`` instantiates an long-lived e-mail-sending connection.
|
||||
|
||||
* ``close()`` closes the current email-sending connection.
|
||||
* ``close()`` closes the current e-mail-sending connection.
|
||||
|
||||
* ``send_messages(email_messages)`` sends a list of
|
||||
:class:`~django.core.mail.EmailMessage` objects. If the connection is
|
||||
@@ -379,11 +379,11 @@ instance of the e-mail backend that you can use.
|
||||
.. function:: get_connection(backend=None, fail_silently=False, *args, **kwargs)
|
||||
|
||||
By default, a call to ``get_connection()`` will return an instance of the
|
||||
email backend specified in :setting:`EMAIL_BACKEND`. If you specify the
|
||||
e-mail backend specified in :setting:`EMAIL_BACKEND`. If you specify the
|
||||
``backend`` argument, an instance of that backend will be instantiated.
|
||||
|
||||
The ``fail_silently`` argument controls how the backend should handle errors.
|
||||
If ``fail_silently`` is True, exceptions during the email sending process
|
||||
If ``fail_silently`` is True, exceptions during the e-mail sending process
|
||||
will be silently ignored.
|
||||
|
||||
All other arguments are passed directly to the constructor of the
|
||||
@@ -391,8 +391,8 @@ e-mail backend.
|
||||
|
||||
Django ships with several e-mail sending backends. With the exception of the
|
||||
SMTP backend (which is the default), these backends are only useful during
|
||||
testing and development. If you have special email sending requirements, you
|
||||
can :ref:`write your own email backend <topic-custom-email-backend>`.
|
||||
testing and development. If you have special e-mail sending requirements, you
|
||||
can :ref:`write your own e-mail backend <topic-custom-email-backend>`.
|
||||
|
||||
.. _topic-email-smtp-backend:
|
||||
|
||||
@@ -414,8 +414,8 @@ want to specify it explicitly, put the following in your settings::
|
||||
|
||||
Prior to version 1.2, Django provided a
|
||||
:class:`~django.core.mail.SMTPConnection` class. This class provided a way
|
||||
to directly control the use of SMTP to send email. This class has been
|
||||
deprecated in favor of the generic email backend API.
|
||||
to directly control the use of SMTP to send e-mail. This class has been
|
||||
deprecated in favor of the generic e-mail backend API.
|
||||
|
||||
For backwards compatibility :class:`~django.core.mail.SMTPConnection` is
|
||||
still available in ``django.core.mail`` as an alias for the SMTP backend.
|
||||
@@ -508,15 +508,15 @@ implementation.
|
||||
|
||||
.. _topics-sending-multiple-emails:
|
||||
|
||||
Sending multiple emails
|
||||
-----------------------
|
||||
Sending multiple e-mails
|
||||
------------------------
|
||||
|
||||
Establishing and closing an SMTP connection (or any other network connection,
|
||||
for that matter) is an expensive process. If you have a lot of emails to send,
|
||||
for that matter) is an expensive process. If you have a lot of e-mails to send,
|
||||
it makes sense to reuse an SMTP connection, rather than creating and
|
||||
destroying a connection every time you want to send an email.
|
||||
destroying a connection every time you want to send an e-mail.
|
||||
|
||||
There are two ways you tell an email backend to reuse a connection.
|
||||
There are two ways you tell an e-mail backend to reuse a connection.
|
||||
|
||||
Firstly, you can use the ``send_messages()`` method. ``send_messages()`` takes
|
||||
a list of :class:`~django.core.mail.EmailMessage` instances (or subclasses),
|
||||
@@ -524,11 +524,11 @@ and sends them all using a single connection.
|
||||
|
||||
For example, if you have a function called ``get_notification_email()`` that
|
||||
returns a list of :class:`~django.core.mail.EmailMessage` objects representing
|
||||
some periodic e-mail you wish to send out, you could send these emails using
|
||||
some periodic e-mail you wish to send out, you could send these e-mails using
|
||||
a single call to send_messages::
|
||||
|
||||
from django.core import mail
|
||||
connection = mail.get_connection() # Use default email connection
|
||||
connection = mail.get_connection() # Use default e-mail connection
|
||||
messages = get_notification_email()
|
||||
connection.send_messages(messages)
|
||||
|
||||
@@ -536,7 +536,7 @@ In this example, the call to ``send_messages()`` opens a connection on the
|
||||
backend, sends the list of messages, and then closes the connection again.
|
||||
|
||||
The second approach is to use the ``open()`` and ``close()`` methods on the
|
||||
email backend to manually control the connection. ``send_messages()`` will not
|
||||
e-mail backend to manually control the connection. ``send_messages()`` will not
|
||||
manually open or close the connection if it is already open, so if you
|
||||
manually open the connection, you can control when it is closed. For example::
|
||||
|
||||
@@ -546,10 +546,10 @@ manually open the connection, you can control when it is closed. For example::
|
||||
# Manually open the connection
|
||||
connection.open()
|
||||
|
||||
# Construct an email message that uses the connection
|
||||
# Construct an e-mail message that uses the connection
|
||||
email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
|
||||
['to1@example.com'], connection=connection)
|
||||
email1.send() # Send the email
|
||||
email1.send() # Send the e-mail
|
||||
|
||||
# Construct two more messages
|
||||
email2 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
|
||||
@@ -557,7 +557,7 @@ manually open the connection, you can control when it is closed. For example::
|
||||
email3 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
|
||||
['to3@example.com'])
|
||||
|
||||
# Send the two emails in a single call -
|
||||
# Send the two e-mails in a single call -
|
||||
connection.send_messages([email2, email3])
|
||||
# The connection was already open so send_messages() doesn't close it.
|
||||
# We need to manually close the connection.
|
||||
@@ -574,10 +574,10 @@ people under the right conditions, and that those e-mails will contain the
|
||||
correct content.
|
||||
|
||||
The easiest way to test your project's use of e-mail is to use the ``console``
|
||||
email backend. This backend redirects all email to stdout, allowing you to
|
||||
e-mail backend. This backend redirects all e-mail to stdout, allowing you to
|
||||
inspect the content of mail.
|
||||
|
||||
The ``file`` email backend can also be useful during development -- this backend
|
||||
The ``file`` e-mail backend can also be useful during development -- this backend
|
||||
dumps the contents of every SMTP connection to a file that can be inspected
|
||||
at your leisure.
|
||||
|
||||
@@ -604,7 +604,7 @@ SMTPConnection
|
||||
|
||||
.. deprecated:: 1.2
|
||||
|
||||
The ``SMTPConnection`` class has been deprecated in favor of the generic email
|
||||
The ``SMTPConnection`` class has been deprecated in favor of the generic e-mail
|
||||
backend API.
|
||||
|
||||
For backwards compatibility ``SMTPConnection`` is still available in
|
||||
|
||||
Reference in New Issue
Block a user