summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorHonza Král <honza.kral@gmail.com>2009-12-28 16:35:23 +0000
committerHonza Král <honza.kral@gmail.com>2009-12-28 16:35:23 +0000
commitf911df19a455246198b0c8c81ab96bf2abec04f8 (patch)
tree0c0bfb72d622994419492db943d9d37857224f97 /docs
parent695de8cc9145e139c2b22e05aa44f5ac04da6f85 (diff)
[soc2009/model-validation] Merget to trunk at r12009
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@12014 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/faq/install.txt2
-rw-r--r--docs/howto/auth-remote-user.txt2
-rw-r--r--docs/howto/custom-model-fields.txt148
-rw-r--r--docs/howto/custom-template-tags.txt79
-rw-r--r--docs/howto/deployment/modpython.txt4
-rw-r--r--docs/howto/initial-data.txt34
-rw-r--r--docs/howto/legacy-databases.txt17
-rw-r--r--docs/howto/outputting-pdf.txt10
-rw-r--r--docs/index.txt6
-rw-r--r--docs/internals/contributing.txt102
-rw-r--r--docs/internals/deprecation.txt48
-rw-r--r--docs/internals/documentation.txt11
-rw-r--r--docs/intro/tutorial01.txt50
-rw-r--r--docs/man/django-admin.14
-rw-r--r--docs/ref/authbackends.txt8
-rw-r--r--docs/ref/contrib/admin/index.txt34
-rw-r--r--docs/ref/contrib/flatpages.txt1
-rw-r--r--docs/ref/contrib/formtools/form-wizard.txt152
-rw-r--r--docs/ref/contrib/index.txt20
-rw-r--r--docs/ref/contrib/localflavor.txt62
-rw-r--r--docs/ref/contrib/messages.txt405
-rw-r--r--docs/ref/contrib/sitemaps.txt4
-rw-r--r--docs/ref/contrib/syndication.txt2
-rw-r--r--docs/ref/databases.txt124
-rw-r--r--docs/ref/django-admin.txt271
-rw-r--r--docs/ref/files/index.txt9
-rw-r--r--docs/ref/forms/api.txt149
-rw-r--r--docs/ref/forms/index.txt5
-rw-r--r--docs/ref/generic-views.txt1
-rw-r--r--docs/ref/index.txt2
-rw-r--r--docs/ref/middleware.txt20
-rw-r--r--docs/ref/models/fields.txt14
-rw-r--r--docs/ref/models/index.txt1
-rw-r--r--docs/ref/models/options.txt6
-rw-r--r--docs/ref/models/querysets.txt37
-rw-r--r--docs/ref/request-response.txt11
-rw-r--r--docs/ref/settings.txt588
-rw-r--r--docs/ref/signals.txt6
-rw-r--r--docs/ref/templates/api.txt147
-rw-r--r--docs/ref/templates/builtins.txt177
-rw-r--r--docs/ref/templates/index.txt7
-rw-r--r--docs/ref/unicode.txt12
-rw-r--r--docs/releases/0.96.txt34
-rw-r--r--docs/releases/1.1-alpha-1.txt13
-rw-r--r--docs/releases/1.1.txt11
-rw-r--r--docs/releases/1.2.txt344
-rw-r--r--docs/topics/auth.txt83
-rw-r--r--docs/topics/db/index.txt1
-rw-r--r--docs/topics/db/multi-db.txt269
-rw-r--r--docs/topics/db/queries.txt13
-rw-r--r--docs/topics/db/sql.txt189
-rw-r--r--docs/topics/db/transactions.txt30
-rw-r--r--docs/topics/files.txt2
-rw-r--r--docs/topics/forms/modelforms.txt8
-rw-r--r--docs/topics/http/file-uploads.txt20
-rw-r--r--docs/topics/http/sessions.txt28
-rw-r--r--docs/topics/http/urls.txt16
-rw-r--r--docs/topics/i18n.txt142
-rw-r--r--docs/topics/install.txt4
-rw-r--r--docs/topics/serialization.txt192
-rw-r--r--docs/topics/templates.txt21
-rw-r--r--docs/topics/testing.txt126
62 files changed, 3649 insertions, 689 deletions
diff --git a/docs/faq/install.txt b/docs/faq/install.txt
index 28a89ccc1f..810247a1bc 100644
--- a/docs/faq/install.txt
+++ b/docs/faq/install.txt
@@ -35,7 +35,7 @@ also need a database engine. PostgreSQL_ is recommended, because we're
PostgreSQL fans, and MySQL_, `SQLite 3`_, and Oracle_ are also supported.
.. _Python: http://www.python.org/
-.. _WSGI: http://www.python.org/peps/pep-0333.html
+.. _WSGI: http://www.python.org/dev/peps/pep-0333/
.. _server arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements
.. _PostgreSQL: http://www.postgresql.org/
.. _MySQL: http://www.mysql.com/
diff --git a/docs/howto/auth-remote-user.txt b/docs/howto/auth-remote-user.txt
index 05532da0b0..b7987e14a7 100644
--- a/docs/howto/auth-remote-user.txt
+++ b/docs/howto/auth-remote-user.txt
@@ -12,7 +12,7 @@ Windows Authentication or Apache and `mod_authnz_ldap`_, `CAS`_, `Cosign`_,
`WebAuth`_, `mod_auth_sspi`_, etc.
.. _mod_authnz_ldap: http://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html
-.. _CAS: http://www.ja-sig.org/products/cas/
+.. _CAS: http://www.jasig.org/cas
.. _Cosign: http://weblogin.org
.. _WebAuth: http://www.stanford.edu/services/webauth/
.. _mod_auth_sspi: http://sourceforge.net/projects/mod-auth-sspi
diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt
index 9f798f14d5..169f5114b8 100644
--- a/docs/howto/custom-model-fields.txt
+++ b/docs/howto/custom-model-fields.txt
@@ -5,6 +5,7 @@ Writing custom model fields
===========================
.. versionadded:: 1.0
+.. currentmodule:: django.db.models
Introduction
============
@@ -39,6 +40,8 @@ are traditionally called *north*, *east*, *south* and *west*. Our class looks
something like this::
class Hand(object):
+ """A hand of cards (bridge style)"""
+
def __init__(self, north, east, south, west):
# Input parameters are lists of cards ('Ah', '9s', etc)
self.north = north
@@ -163,6 +166,9 @@ behave like any existing field, so we'll subclass directly from
from django.db import models
class HandField(models.Field):
+
+ description = "A hand of cards (bridge style)"
+
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 104
super(HandField, self).__init__(*args, **kwargs)
@@ -244,6 +250,9 @@ simple: make sure your field subclass uses a special metaclass:
For example::
class HandField(models.Field):
+
+ description = "A hand of cards (bridge style)"
+
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
@@ -252,6 +261,22 @@ For example::
This ensures that the :meth:`to_python` method, documented below, will always be
called when the attribute is initialized.
+
+Documenting your Custom Field
+-----------------------------
+
+.. class:: django.db.models.Field
+
+.. attribute:: description
+
+As always, you should document your field type, so users will know what it is.
+In addition to providing a docstring for it, which is useful for developers,
+you can also allow users of the admin app to see a short description of the
+field type via the ``django.contrib.admindocs`` application. To do this simply
+provide descriptive text in a ``description`` class attribute of your custom field.
+In the above example, the type description displayed by the ``admindocs`` application
+for a ``HandField`` will be 'A hand of cards (bridge style)'.
+
Useful methods
--------------
@@ -263,10 +288,13 @@ approximately decreasing order of importance, so start from the top.
Custom database types
~~~~~~~~~~~~~~~~~~~~~
-.. method:: db_type(self)
+.. method:: db_type(self, connection)
+
+.. versionadded:: 1.2
+ The ``connection`` argument was added to support multiple databases.
Returns the database column data type for the :class:`~django.db.models.Field`,
-taking into account the current :setting:`DATABASE_ENGINE` setting.
+taking into account the connection object, and the settings associated with it.
Say you've created a PostgreSQL custom type called ``mytype``. You can use this
field with Django by subclassing ``Field`` and implementing the :meth:`db_type`
@@ -275,7 +303,7 @@ method, like so::
from django.db import models
class MytypeField(models.Field):
- def db_type(self):
+ def db_type(self, connection):
return 'mytype'
Once you have ``MytypeField``, you can use it in any model, just like any other
@@ -290,13 +318,13 @@ If you aim to build a database-agnostic application, you should account for
differences in database column types. For example, the date/time column type
in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
``datetime``. The simplest way to handle this in a ``db_type()`` method is to
-import the Django settings module and check the :setting:`DATABASE_ENGINE` setting.
+check the ``connection.settings_dict['ENGINE']`` attribute.
+
For example::
class MyDateField(models.Field):
- def db_type(self):
- from django.conf import settings
- if settings.DATABASE_ENGINE == 'mysql':
+ def db_type(self, connection):
+ if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
return 'datetime'
else:
return 'timestamp'
@@ -304,7 +332,7 @@ For example::
The :meth:`db_type` method is only called by Django when the framework
constructs the ``CREATE TABLE`` statements for your application -- that is, when
you first create your tables. It's not called at any other time, so it can
-afford to execute slightly complex code, such as the :setting:`DATABASE_ENGINE`
+afford to execute slightly complex code, such as the ``connection.settings_dict``
check in the above example.
Some database column types accept parameters, such as ``CHAR(25)``, where the
@@ -315,7 +343,7 @@ sense to have a ``CharMaxlength25Field``, shown here::
# This is a silly example of hard-coded parameters.
class CharMaxlength25Field(models.Field):
- def db_type(self):
+ def db_type(self, connection):
return 'char(25)'
# In the model:
@@ -333,7 +361,7 @@ time -- i.e., when the class is instantiated. To do that, just implement
self.max_length = max_length
super(BetterCharField, self).__init__(*args, **kwargs)
- def db_type(self):
+ def db_type(self, connection):
return 'char(%s)' % self.max_length
# In the model:
@@ -396,33 +424,67 @@ Python object type we want to store in the model's attribute.
called when it is created, you should be using `The SubfieldBase metaclass`_
mentioned earlier. Otherwise :meth:`to_python` won't be called automatically.
-Converting Python objects to database values
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Converting Python objects to query values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_prep_value(self, value)
-.. method:: get_db_prep_value(self, value)
+.. versionadded:: 1.2
+ This method was factored out of ``get_db_prep_value()``
-This is the reverse of :meth:`to_python` when working with the database backends
-(as opposed to serialization). The ``value`` parameter is the current value of
-the model's attribute (a field has no reference to its containing model, so it
-cannot retrieve the value itself), and the method should return data in a format
-that can be used as a parameter in a query for the database backend.
+This is the reverse of :meth:`to_python` when working with the
+database backends (as opposed to serialization). The ``value``
+parameter is the current value of the model's attribute (a field has
+no reference to its containing model, so it cannot retrieve the value
+itself), and the method should return data in a format that has been
+prepared for use as a parameter in a query.
+
+This conversion should *not* include any database-specific
+conversions. If database-specific conversions are required, they
+should be made in the call to :meth:`get_db_prep_value`.
For example::
class HandField(models.Field):
# ...
- def get_db_prep_value(self, value):
+ def get_prep_value(self, value):
return ''.join([''.join(l) for l in (value.north,
value.east, value.south, value.west)])
-.. method:: get_db_prep_save(self, value)
+Converting query values to database values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_db_prep_value(self, value, connection, prepared=False)
+
+.. versionadded:: 1.2
+ The ``connection`` and ``prepared`` arguments were added to support multiple databases.
+
+Some data types (for example, dates) need to be in a specific format
+before they can be used by a database backend.
+:meth:`get_db_prep_value` is the method where those conversions should
+be made. The specific connection that will be used for the query is
+passed as the ``connection`` parameter. This allows you to use
+backend-specific conversion logic if it is required.
+
+The ``prepared`` argument describes whether or not the value has
+already been passed through :meth:`get_prep_value` conversions. When
+``prepared`` is False, the default implementation of
+:meth:`get_db_prep_value` will call :meth:`get_prep_value` to do
+initial data conversions before performing any database-specific
+processing.
+
+.. method:: get_db_prep_save(self, value, connection)
+
+.. versionadded:: 1.2
+ The ``connection`` argument was added to support multiple databases.
-Same as the above, but called when the Field value must be *saved* to the
-database. As the default implementation just calls ``get_db_prep_value``, you
-shouldn't need to implement this method unless your custom field needs a
-special conversion when being saved that is not the same as the conversion used
-for normal query parameters (which is implemented by ``get_db_prep_value``).
+Same as the above, but called when the Field value must be *saved* to
+the database. As the default implementation just calls
+``get_db_prep_value``, you shouldn't need to implement this method
+unless your custom field needs a special conversion when being saved
+that is not the same as the conversion used for normal query
+parameters (which is implemented by ``get_db_prep_value``).
Preprocessing values before saving
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -450,7 +512,16 @@ correct value.
Preparing values for use in database lookups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. method:: get_db_prep_lookup(self, lookup_type, value)
+As with value conversions, preparing a value for database lookups is a
+two phase process.
+
+.. method:: get_prep_lookup(self, lookup_type, value)
+
+.. versionadded:: 1.2
+ This method was factored out of ``get_db_prep_lookup()``
+
+:meth:`get_prep_lookup` performs the first phase of lookup preparation,
+performing generic data validity checks
Prepares the ``value`` for passing to the database when used in a lookup (a
``WHERE`` constraint in SQL). The ``lookup_type`` will be one of the valid
@@ -467,34 +538,45 @@ by with handling the lookup types that need special handling for your field
and pass the rest to the :meth:`get_db_prep_lookup` method of the parent class.
If you needed to implement ``get_db_prep_save()``, you will usually need to
-implement ``get_db_prep_lookup()``. If you don't, ``get_db_prep_value`` will be
+implement ``get_prep_lookup()``. If you don't, ``get_prep_value`` will be
called by the default implementation, to manage ``exact``, ``gt``, ``gte``,
``lt``, ``lte``, ``in`` and ``range`` lookups.
You may also want to implement this method to limit the lookup types that could
be used with your custom field type.
-Note that, for ``range`` and ``in`` lookups, ``get_db_prep_lookup`` will receive
+Note that, for ``range`` and ``in`` lookups, ``get_prep_lookup`` will receive
a list of objects (presumably of the right type) and will need to convert them
to a list of things of the right type for passing to the database. Most of the
-time, you can reuse ``get_db_prep_value()``, or at least factor out some common
+time, you can reuse ``get_prep_value()``, or at least factor out some common
pieces.
-For example, the following code implements ``get_db_prep_lookup`` to limit the
+For example, the following code implements ``get_prep_lookup`` to limit the
accepted lookup types to ``exact`` and ``in``::
class HandField(models.Field):
# ...
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_prep_lookup(self, lookup_type, value):
# We only handle 'exact' and 'in'. All others are errors.
if lookup_type == 'exact':
- return [self.get_db_prep_value(value)]
+ return [self.get_prep_value(value)]
elif lookup_type == 'in':
- return [self.get_db_prep_value(v) for v in value]
+ return [self.get_prep_value(v) for v in value]
else:
raise TypeError('Lookup type %r not supported.' % lookup_type)
+.. method:: get_db_prep_lookup(self, lookup_type, value, connection, prepared=False)
+
+.. versionadded:: 1.2
+ The ``connection`` and ``prepared`` arguments were added to support multiple databases.
+
+Performs any database-specific data conversions required by a lookup.
+As with :meth:`get_db_prep_value`, the specific connection that will
+be used for the query is passed as the ``connection`` parameter.
+The ``prepared`` argument describes whether the value has already been
+prepared with :meth:`get_prep_lookup`.
+
Specifying the form field for a model field
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt
index c6f76772de..774d12dc44 100644
--- a/docs/howto/custom-template-tags.txt
+++ b/docs/howto/custom-template-tags.txt
@@ -463,6 +463,85 @@ new ``Context`` in this example, the results would have *always* been
automatically escaped, which may not be the desired behavior if the template
tag is used inside a ``{% autoescape off %}`` block.
+.. _template_tag_thread_safety:
+
+Thread-safety considerations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+Once a node is parsed, its ``render`` method may be called any number of times.
+Since Django is sometimes run in multi-threaded environments, a single node may
+be simultaneously rendering with different contexts in response to two separate
+requests. Therefore, it's important to make sure your template tags are thread
+safe.
+
+To make sure your template tags are thread safe, you should never store state
+information on the node itself. For example, Django provides a builtin ``cycle``
+template tag that cycles among a list of given strings each time it's rendered::
+
+ {% for o in some_list %}
+ <tr class="{% cycle 'row1' 'row2' %}>
+ ...
+ </tr>
+ {% endfor %}
+
+A naive implementation of ``CycleNode`` might look something like this::
+
+ class CycleNode(Node):
+ def __init__(self, cyclevars):
+ self.cycle_iter = itertools.cycle(cyclevars)
+ def render(self, context):
+ return self.cycle_iter.next()
+
+But, suppose we have two templates rendering the template snippet from above at
+the same time:
+
+ 1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
+ returns 'row1'
+ 2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
+ returns 'row2'
+ 3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
+ returns 'row1'
+ 4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
+ returns 'row2'
+
+The CycleNode is iterating, but it's iterating globally. As far as Thread 1
+and Thread 2 are concerned, it's always returning the same value. This is
+obviously not what we want!
+
+To address this problem, Django provides a ``render_context`` that's associated
+with the ``context`` of the template that is currently being rendered. The
+``render_context`` behaves like a Python dictionary, and should be used to store
+``Node`` state between invocations of the ``render`` method.
+
+Let's refactor our ``CycleNode`` implementation to use the ``render_context``::
+
+ class CycleNode(Node):
+ def __init__(self, cyclevars):
+ self.cyclevars = cyclevars
+ def render(self, context):
+ if self not in context.render_context:
+ context.render_context[self] = itertools.cycle(self.cyclevars)
+ cycle_iter = context.render_context[self]
+ return cycle_iter.next()
+
+Note that it's perfectly safe to store global information that will not change
+throughout the life of the ``Node`` as an attribute. In the case of
+``CycleNode``, the ``cyclevars`` argument doesn't change after the ``Node`` is
+instantiated, so we don't need to put it in the ``render_context``. But state
+information that is specific to the template that is currently being rendered,
+like the current iteration of the ``CycleNode``, should be stored in the
+``render_context``.
+
+.. note::
+ Notice how we used ``self`` to scope the ``CycleNode`` specific information
+ within the ``render_context``. There may be multiple ``CycleNodes`` in a
+ given template, so we need to be careful not to clobber another node's state
+ information. The easiest way to do this is to always use ``self`` as the key
+ into ``render_context``. If you're keeping track of several state variables,
+ make ``render_context[self]`` a dictionary.
+
Registering the tag
~~~~~~~~~~~~~~~~~~~
diff --git a/docs/howto/deployment/modpython.txt b/docs/howto/deployment/modpython.txt
index 50dadf9854..143a6d5ae3 100644
--- a/docs/howto/deployment/modpython.txt
+++ b/docs/howto/deployment/modpython.txt
@@ -375,9 +375,9 @@ set of imports until it stops crashing, so as to find the specific module that
causes the problem. Drop down further into modules and look into their imports,
as necessary.
-.. _Expat Causing Apache Crash: http://www.dscpl.com.au/articles/modpython-006.html
+.. _Expat Causing Apache Crash: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCrash
.. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp
-.. _Getting mod_python Working: http://www.dscpl.com.au/articles/modpython-001.html
+.. _Getting mod_python Working: http://www.dscpl.com.au/wiki/ModPython/Articles/GettingModPythonWorking
If you get a UnicodeEncodeError
===============================
diff --git a/docs/howto/initial-data.txt b/docs/howto/initial-data.txt
index d36329daa4..b071d6d529 100644
--- a/docs/howto/initial-data.txt
+++ b/docs/howto/initial-data.txt
@@ -118,23 +118,27 @@ The SQL files are read by the :djadmin:`sqlcustom`, :djadmin:`sqlreset`,
<ref-django-admin>`. Refer to the :ref:`manage.py documentation
<ref-django-admin>` for more information.
-Note that if you have multiple SQL data files, there's no guarantee of the order
-in which they're executed. The only thing you can assume is that, by the time
-your custom data files are executed, all the database tables already will have
-been created.
+Note that if you have multiple SQL data files, there's no guarantee of
+the order in which they're executed. The only thing you can assume is
+that, by the time your custom data files are executed, all the
+database tables already will have been created.
Database-backend-specific SQL data
----------------------------------
-There's also a hook for backend-specific SQL data. For example, you can have
-separate initial-data files for PostgreSQL and MySQL. For each app, Django
-looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where
-``<appname>`` is your app directory, ``<modelname>`` is the model's name in
-lowercase and ``<backend>`` is the value of :setting:`DATABASE_ENGINE` in your
-settings file (e.g., ``postgresql``, ``mysql``).
+There's also a hook for backend-specific SQL data. For example, you
+can have separate initial-data files for PostgreSQL and MySQL. For
+each app, Django looks for a file called
+``<appname>/sql/<modelname>.<backend>.sql``, where ``<appname>`` is
+your app directory, ``<modelname>`` is the model's name in lowercase
+and ``<backend>`` is the last part of the module name provided for the
+:setting:`ENGINE` in your settings file (e.g., if you have defined a
+database with an :setting:`ENGINE` value of
+``django.db.backends.postgresql``, Django will look for
+``<appname>/sql/<modelname>.postgresql.sql``).
-Backend-specific SQL data is executed before non-backend-specific SQL data. For
-example, if your app contains the files ``sql/person.sql`` and
-``sql/person.postgresql.sql`` and you're installing the app on PostgreSQL,
-Django will execute the contents of ``sql/person.postgresql.sql`` first, then
-``sql/person.sql``.
+Backend-specific SQL data is executed before non-backend-specific SQL
+data. For example, if your app contains the files ``sql/person.sql``
+and ``sql/person.postgresql.sql`` and you're installing the app on
+PostgreSQL, Django will execute the contents of
+``sql/person.postgresql.sql`` first, then ``sql/person.sql``.
diff --git a/docs/howto/legacy-databases.txt b/docs/howto/legacy-databases.txt
index c4eb1d82c7..b2aa7e4ea6 100644
--- a/docs/howto/legacy-databases.txt
+++ b/docs/howto/legacy-databases.txt
@@ -18,15 +18,16 @@ Give Django your database parameters
====================================
You'll need to tell Django what your database connection parameters are, and
-what the name of the database is. Do that by editing these settings in your
-:ref:`settings file <topics-settings>`:
+what the name of the database is. Do that by editing the :setting:`DATABASES`
+setting and assigning values to the following keys for the ``'default'``
+connection:
- * :setting:`DATABASE_NAME`
- * :setting:`DATABASE_ENGINE`
- * :setting:`DATABASE_USER`
- * :setting:`DATABASE_PASSWORD`
- * :setting:`DATABASE_HOST`
- * :setting:`DATABASE_PORT`
+ * :setting:`NAME`
+ * :setting:`ENGINE`
+ * :setting:`USER`
+ * :setting:`PASSWORD`
+ * :setting:`HOST`
+ * :setting:`PORT`
Auto-generate the models
========================
diff --git a/docs/howto/outputting-pdf.txt b/docs/howto/outputting-pdf.txt
index 3cbab555e4..94acab8311 100644
--- a/docs/howto/outputting-pdf.txt
+++ b/docs/howto/outputting-pdf.txt
@@ -16,13 +16,13 @@ For example, Django was used at kusports.com_ to generate customized,
printer-friendly NCAA tournament brackets, as PDF files, for people
participating in a March Madness contest.
-.. _ReportLab: http://www.reportlab.org/rl_toolkit.html
+.. _ReportLab: http://www.reportlab.org/oss/rl-toolkit/
.. _kusports.com: http://www.kusports.com/
Install ReportLab
=================
-Download and install the ReportLab library from http://www.reportlab.org/downloads.html.
+Download and install the ReportLab library from http://www.reportlab.org/oss/rl-toolkit/download/.
The `user guide`_ (not coincidentally, a PDF file) explains how to install it.
Test your installation by importing it in the Python interactive interpreter::
@@ -138,17 +138,15 @@ Further resources
* PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.
- * `Pisa HTML2PDF`_ is yet another PDF-generation library. Pisa ships with
+ * `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python.
- * `forge_fdf in Python`_ is a library that fills in PDF forms.
.. _PDFlib: http://www.pdflib.org/
-.. _`Pisa HTML2PDF`: http://www.htmltopdf.org/
+.. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/
.. _HTMLdoc: http://www.htmldoc.org/
-.. _forge_fdf in Python: http://www.accesspdf.com/article.php/20050421092951834
Other formats
=============
diff --git a/docs/index.txt b/docs/index.txt
index 0ba727280c..e6558a7478 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -28,7 +28,7 @@ Having trouble? We'd like to help!
.. _archives of the django-users mailing list: http://groups.google.com/group/django-users/
.. _post a question: http://groups.google.com/group/django-users/
.. _#django IRC channel: irc://irc.freenode.net/django
-.. _IRC logs: http://oebfare.com/logger/django/
+.. _IRC logs: http://botland.oebfare.com/logger/django/
.. _ticket tracker: http://code.djangoproject.com/
First steps
@@ -65,7 +65,8 @@ The model layer
:ref:`Raw SQL <topics-db-sql>` |
:ref:`Transactions <topics-db-transactions>` |
:ref:`Aggregation <topics-db-aggregation>` |
- :ref:`Custom fields <howto-custom-model-fields>`
+ :ref:`Custom fields <howto-custom-model-fields>` |
+ :ref:`Multiple databases <topics-db-multi-db>`
* **Other:**
:ref:`Supported databases <ref-databases>` |
@@ -170,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>`
diff --git a/docs/internals/contributing.txt b/docs/internals/contributing.txt
index 1f1161de43..43909e3828 100644
--- a/docs/internals/contributing.txt
+++ b/docs/internals/contributing.txt
@@ -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 containing 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
============
@@ -752,27 +793,53 @@ To run the tests, ``cd`` to the ``tests/`` directory and type:
./runtests.py --settings=path.to.django.settings
Yes, the unit tests need a settings module, but only for database connection
-info, with the ``DATABASE_ENGINE`` setting.
+info. Your :setting:`DATABASES` setting needs to define two databases:
+
+ * A ``default`` database. This database should use the backend that
+ you want to use for primary testing
+
+ * A database with the alias ``other``. The ``other`` database is
+ used to establish that queries can be directed to different
+ databases. As a result, this database can use any backend you
+ want. It doesn't need to use the same backend as the ``default``
+ database (although it can use the same backend if you want to).
+
+If you're using the SQLite database backend, you need to define
+:setting:`ENGINE` for both databases, plus a
+:setting:`TEST_NAME` for the ``other`` database. The
+following is a minimal settings file that can be used to test SQLite::
+
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3'
+ },
+ 'other': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'TEST_NAME': 'other_db'
+ }
+ }
+
-If you're using the ``sqlite3`` database backend, no further settings are
-needed. A temporary database will be created in memory when running the tests.
+If you're using another backend, you will need to provide other details for
+each database:
-If you're using another backend:
+ * The :setting:`USER` option for each of your databases needs to
+ specify an existing user account for the database.
- * Your :setting:`DATABASE_USER` setting needs to specify an existing user account
- for the database engine.
+ * The :setting:`PASSWORD` option needs to provide the password for
+ the :setting:`USER` that has been specified.
- * The :setting:`DATABASE_NAME` setting must be the name of an existing database to
+ * The :setting:`NAME` option must be the name of an existing database to
which the given user has permission to connect. The unit tests will not
touch this database; the test runner creates a new database whose name is
- :setting:`DATABASE_NAME` prefixed with ``test_``, and this test database is
+ :setting:`NAME` prefixed with ``test_``, and this test database is
deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``.
You will also need to ensure that your database uses UTF-8 as the default
character set. If your database server doesn't use UTF-8 as a default charset,
-you will need to include a value for ``TEST_DATABASE_CHARSET`` in your settings
-file.
+you will need to include a value for ``TEST_CHARSET`` in the settings
+dictionary for the applicable database.
If you want to run the full suite of tests, you'll need to install a number of
dependencies:
@@ -782,7 +849,8 @@ dependencies:
* Textile_
* Docutils_
* setuptools_
- * memcached_, plus the either the python-memcached_ or cmemcached_ Python binding
+ * memcached_, plus the either the python-memcached_ or cmemcached_
+ Python binding
If you want to test the memcached cache backend, you will also need to define
a :setting:`CACHE_BACKEND` setting that points at your memcached instance.
@@ -797,7 +865,7 @@ associated tests will be skipped.
.. _setuptools: http://pypi.python.org/pypi/setuptools/
.. _memcached: http://www.danga.com/memcached/
.. _python-memcached: http://pypi.python.org/pypi/python-memcached/
-.. _cmemcached: http://pypi.python.org/pypi/cmemcache
+.. _cmemcached: http://gijsbert.org/cmemcache/index.html
To run a subset of the unit tests, append the names of the test modules to the
``runtests.py`` command line. See the list of directories in
@@ -892,9 +960,9 @@ for feature branches:
If you want a feature branch in SVN, you'll need to ask in
`django-developers`_ for a mentor.
-.. _git: http://git.or.cz/
-.. _mercurial: http://www.selenic.com/mercurial/
-.. _bazaar: http://bazaar-vcs.org/
+.. _git: http://git-scm.com/
+.. _mercurial: http://mercurial.selenic.com/
+.. _bazaar: http://bazaar.canonical.com/
.. _django branches: http://code.djangoproject.com/wiki/DjangoBranches
Branch rules
@@ -1026,7 +1094,7 @@ If you're using Django 0.95 or earlier and installed it using
file. Then copy the branch's version of the ``django`` directory into
``site-packages``.
-.. _path file: http://docs.python.org/lib/module-site.html
+.. _path file: http://docs.python.org/library/site.html
Deciding on features
====================
@@ -1092,6 +1160,6 @@ requests for commit access are potential flame-war starters, and will be ignored
.. _django-users: http://groups.google.com/group/django-users
.. _`#django`: irc://irc.freenode.net/django
.. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
-.. _pep8.py: http://svn.browsershots.org/trunk/devtools/pep8/pep8.py
+.. _pep8.py: http://pypi.python.org/pypi/pep8/
.. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n
.. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 480b527d6b..1bd58ec0b3 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -13,6 +13,10 @@ their deprecation, as per the :ref:`Django deprecation policy
hooking up admin URLs. This has been deprecated since the 1.1
release.
+ * Authentication backends need to define the boolean attribute
+ ``supports_object_permissions``. The old backend style is deprecated
+ since the 1.2 release.
+
* 1.4
* ``CsrfResponseMiddleware``. This has been deprecated since the 1.2
release, in favour of the template tag method for inserting the CSRF
@@ -26,7 +30,49 @@ their deprecation, as per the :ref:`Django deprecation policy
class in favor of a generic E-mail backend API.
* The many to many SQL generation functions on the database backends
- will be removed. These have been deprecated since the 1.2 release.
+ will be removed.
+
+ * The ability to use the ``DATABASE_*`` family of top-level settings to
+ define database connections will be removed.
+
+ * The ability to use shorthand notation to specify a database backend
+ (i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be
+ removed.
+
+ * The ``get_db_prep_save``, ``get_db_prep_value`` and
+ ``get_db_prep_lookup`` methods on Field were modified in 1.2 to support
+ 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.
+
+ * Authentication backends need to support the ``obj`` parameter for
+ permission checking. The ``supports_object_permissions`` variable
+ is not checked any longer and can be removed.
+
+ * The ability to specify a callable template loader rather than a
+ ``Loader`` class will be removed, as will the ``load_template_source``
+ functions that are included with the built in template loaders for
+ backwards compatibility. These have been deprecated since the 1.2
+ release.
+
+ * ``django.utils.translation.get_date_formats()`` and
+ ``django.utils.translation.get_partial_date_formats()``. These
+ functions are replaced by the new locale aware formatting; use
+ ``django.utils.formats.get_format()`` to get the appropriate
+ formats.
+
+ * In ``django.forms.fields``: ``DEFAULT_DATE_INPUT_FORMATS``,
+ ``DEFAULT_TIME_INPUT_FORMATS`` and
+ ``DEFAULT_DATETIME_INPUT_FORMATS``. Use
+ ``django.utils.formats.get_format()`` to get the appropriate
+ formats.
* 2.0
* ``django.views.defaults.shortcut()``. This function has been moved
diff --git a/docs/internals/documentation.txt b/docs/internals/documentation.txt
index f33af32597..81480abf9a 100644
--- a/docs/internals/documentation.txt
+++ b/docs/internals/documentation.txt
@@ -10,7 +10,7 @@ based on docutils__. The basic idea is that lightly-formatted plain-text
documentation is transformed into HTML, PDF, and any other output format.
__ http://sphinx.pocoo.org/
-__ http://docutils.sf.net/
+__ http://docutils.sourceforge.net/
To actually build the documentation locally, you'll currently need to install
Sphinx -- ``easy_install Sphinx`` should do the trick.
@@ -130,15 +130,6 @@ TODO
The work is mostly done, but here's what's left, in rough order of priority.
- * Change the "Added/changed in development version" callouts to proper
- Sphinx ``.. versionadded::`` or ``.. versionchanged::`` directives.
-
- * Check for and fix malformed links. Do this by running ``make linkcheck``
- and fix all of the 300+ errors/warnings.
-
- In particular, look at all the relative links; these need to be
- changed to proper references.
-
* Most of the various ``index.txt`` documents have *very* short or even
non-existent intro text. Each of those documents needs a good short intro
the content below that point.
diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt
index afda1f28a2..c2864b8f38 100644
--- a/docs/intro/tutorial01.txt
+++ b/docs/intro/tutorial01.txt
@@ -102,7 +102,7 @@ These files are:
contents" of your Django-powered site. You can read more about URLs in
:ref:`topics-http-urls`.
-.. _more about packages: http://docs.python.org/tut/node8.html#packages
+.. _more about packages: http://docs.python.org/tutorial/modules.html#packages
The development server
----------------------
@@ -158,34 +158,40 @@ It worked!
Database setup
--------------
-Now, edit :file:`settings.py`. It's a normal Python module with module-level
-variables representing Django settings. Change these settings to match your
-database's connection parameters:
+Now, edit :file:`settings.py`. It's a normal Python module with
+module-level variables representing Django settings. Change the
+following keys in the :setting:`DATABASES` ``'default'`` item to match
+your databases connection settings.
- * :setting:`DATABASE_ENGINE` -- Either 'postgresql_psycopg2', 'mysql' or
- 'sqlite3'. Other backends are :setting:`also available <DATABASE_ENGINE>`.
+ * :setting:`ENGINE` -- Either
+ ``'django.db.backends.postgresql_psycopg2'``,
+ ``'django.db.backends.mysql'`` or
+ ``'django.db.backends.sqlite3'``. Other backends are
+ :setting:`also available <ENGINE>`.
- * :setting:`DATABASE_NAME` -- The name of your database. If you're using
- SQLite, the database will be a file on your computer; in that case,
- ``DATABASE_NAME`` should be the full absolute path, including filename, of
- that file. If the file doesn't exist, it will automatically be created
- when you synchronize the database for the first time (see below).
+ * :setting:`NAME` -- The name of your database. If you're using
+ SQLite, the database will be a file on your computer; in that
+ case, :setting:`NAME` should be the full absolute path,
+ including filename, of that file. If the file doesn't exist, it
+ will automatically be created when you synchronize the database
+ for the first time (see below).
- When specifying the path, always use forward slashes, even on Windows
- (e.g. ``C:/homes/user/mysite/sqlite3.db``).
+ When specifying the path, always use forward slashes, even on
+ Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
- * :setting:`DATABASE_USER` -- Your database username (not used for SQLite).
+ * :setting:`USER` -- Your database username (not used for SQLite).
- * :setting:`DATABASE_PASSWORD` -- Your database password (not used for
+ * :setting:`PASSWORD` -- Your database password (not used for
SQLite).
- * :setting:`DATABASE_HOST` -- The host your database is on. Leave this as an
- empty string if your database server is on the same physical machine (not
- used for SQLite).
+ * :setting:`HOST` -- The host your database is on. Leave this as
+ an empty string if your database server is on the same physical
+ machine (not used for SQLite).
-If you're new to databases, we recommend simply using SQLite (by setting
-:setting:`DATABASE_ENGINE` to ``'sqlite3'``). SQLite is included as part of
-Python 2.5 and later, so you won't need to install anything else.
+If you're new to databases, we recommend simply using SQLite (by
+setting :setting:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite
+is included as part of Python 2.5 and later, so you won't need to
+install anything else.
.. note::
@@ -361,7 +367,7 @@ Finally, note a relationship is defined, using
to a single Poll. Django supports all the common database relationships:
many-to-ones, many-to-manys and one-to-ones.
-.. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
+.. _`Python path`: http://docs.python.org/tutorial/modules.html#the-module-search-path
Activating models
=================
diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1
index 6407ee5e1d..dff7d0d3da 100644
--- a/docs/man/django-admin.1
+++ b/docs/man/django-admin.1
@@ -28,8 +28,8 @@ Compiles .po files to .mo files for use with builtin gettext support.
Creates the table needed to use the SQL cache backend
.TP
.B dbshell
-Runs the command\-line client for the current
-.BI DATABASE_ENGINE.
+Runs the command\-line client for the specified
+.BI database ENGINE.
.TP
.B diffsettings
Displays differences between the current
diff --git a/docs/ref/authbackends.txt b/docs/ref/authbackends.txt
index 7cb54df7ea..0e98c21b21 100644
--- a/docs/ref/authbackends.txt
+++ b/docs/ref/authbackends.txt
@@ -1,14 +1,14 @@
.. _ref-authentication-backends:
-==========================================
-Built-in authentication backends reference
-==========================================
+=======================
+Authentication backends
+=======================
.. module:: django.contrib.auth.backends
:synopsis: Django's built-in authentication backend classes.
This document details the authentication backends that come with Django. For
-information on how how to use them and how to write your own authentication
+information on how to use them and how to write your own authentication
backends, see the :ref:`Other authentication sources section
<authentication-backends>` of the :ref:`User authentication guide
<topics-auth>`.
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index 0f746bf01b..97e9c8bcc9 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -172,6 +172,11 @@ The ``field_options`` dictionary can have the following keys:
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}
+ .. versionadded:: 1.2
+
+ ``fields`` can contain values defined in
+ :attr:`ModelAdmin.readonly_fields` to be displayed as read-only.
+
* ``classes``
A list containing extra CSS classes to apply to the fieldset.
@@ -210,6 +215,11 @@ the ``django.contrib.flatpages.FlatPage`` model as follows::
In the above example, only the fields 'url', 'title' and 'content' will be
displayed, sequentially, in the form.
+.. versionadded:: 1.2
+
+``fields`` can contain values defined in :attr:`ModelAdmin.readonly_fields`
+to be displayed as read-only.
+
.. admonition:: Note
This ``fields`` option should not be confused with the ``fields``
@@ -540,6 +550,21 @@ into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)
+.. attribute:: ModelAdmin.readonly_fields
+
+.. versionadded:: 1.2
+
+By default the admin shows all fields as editable. Any fields in this option
+(which should be a ``list`` or ``tuple``) will display its data as-is and
+non-editable. This option behaves nearly identical to :attr:`ModelAdmin.list_display`.
+Usage is the same, however, when you specify :attr:`ModelAdmin.fields` or
+:attr:`ModelAdmin.fieldsets` the read-only fields must be present to be shown
+(they are ignored otherwise).
+
+If ``readonly_fields`` is used without defining explicit ordering through
+:attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` they will be added
+last after all editable fields.
+
.. attribute:: ModelAdmin.save_as
Set ``save_as`` to enable a "save as" feature on admin change forms.
@@ -744,6 +769,15 @@ model instance::
instance.save()
formset.save_m2m()
+.. method:: ModelAdmin.get_readonly_fields(self, request, obj=None)
+
+.. versionadded:: 1.2
+
+The ``get_readonly_fields`` method is given the ``HttpRequest`` and the
+``obj`` being edited (or ``None`` on an add form) and is expected to return a
+``list`` or ``tuple`` of field names that will be displayed as read-only, as
+described above in the :attr:`ModelAdmin.readonly_fields` section.
+
.. method:: ModelAdmin.get_urls(self)
.. versionadded:: 1.1
diff --git a/docs/ref/contrib/flatpages.txt b/docs/ref/contrib/flatpages.txt
index 875a1c05e5..f934919412 100644
--- a/docs/ref/contrib/flatpages.txt
+++ b/docs/ref/contrib/flatpages.txt
@@ -26,7 +26,6 @@ content in a custom template.
Here are some examples of flatpages on Django-powered sites:
- * http://www.chicagocrime.org/about/
* http://www.everyblock.com/about/
* http://www.lawrence.com/about/contact/
diff --git a/docs/ref/contrib/formtools/form-wizard.txt b/docs/ref/contrib/formtools/form-wizard.txt
index 11a2aed091..0449bb9cd0 100644
--- a/docs/ref/contrib/formtools/form-wizard.txt
+++ b/docs/ref/contrib/formtools/form-wizard.txt
@@ -47,36 +47,34 @@ Usage
This application handles as much machinery for you as possible. Generally, you
just have to do these things:
- 1. Define a number of :mod:`django.forms`
- :class:`~django.forms.forms.Form` classes -- one per wizard page.
-
- 2. Create a :class:`~django.contrib.formtools.wizard.FormWizard` class
- that specifies what to do once all of your forms have been submitted
- and validated. This also lets you override some of the wizard's behavior.
-
+ 1. Define a number of :class:`~django.forms.Form` classes -- one per wizard
+ page.
+
+ 2. Create a :class:`FormWizard` class that specifies what to do once all of
+ your forms have been submitted and validated. This also lets you
+ override some of the wizard's behavior.
+
3. Create some templates that render the forms. You can define a single,
generic template to handle every one of the forms, or you can define a
specific template for each form.
-
- 4. Point your URLconf at your
- :class:`~django.contrib.formtools.wizard.FormWizard` class.
+
+ 4. Point your URLconf at your :class:`FormWizard` class.
Defining ``Form`` classes
=========================
-The first step in creating a form wizard is to create the :class:`~django.forms.forms.Form` classes.
-These should be standard :mod:`django.forms`
-:class:`~django.forms.forms.Form` classes, covered in the
-:ref:`forms documentation <topics-forms-index>`.
-
-These classes can live anywhere in your codebase, but convention is to put them
-in a file called :file:`forms.py` in your application.
+The first step in creating a form wizard is to create the
+:class:`~django.forms.Form` classes. These should be standard
+:class:`django.forms.Form` classes, covered in the :ref:`forms documentation
+<topics-forms-index>`. These classes can live anywhere in your codebase, but
+convention is to put them in a file called :file:`forms.py` in your
+application.
For example, let's write a "contact form" wizard, where the first page's form
collects the sender's e-mail address and subject, and the second page collects
the message itself. Here's what the :file:`forms.py` might look like::
- from django import forms
+ from django import forms
class ContactForm1(forms.Form):
subject = forms.CharField(max_length=100)
@@ -86,27 +84,27 @@ the message itself. Here's what the :file:`forms.py` might look like::
message = forms.CharField(widget=forms.Textarea)
**Important limitation:** Because the wizard uses HTML hidden fields to store
-data between pages, you may not include a :class:`~django.forms.fields.FileField`
+data between pages, you may not include a :class:`~django.forms.FileField`
in any form except the last one.
Creating a ``FormWizard`` class
===============================
-The next step is to create a :class:`~django.contrib.formtools.wizard.FormWizard`
-class, which should be a subclass of ``django.contrib.formtools.wizard.FormWizard``.
-
-As with your :class:`~django.forms.forms.Form` classes, this
-:class:`~django.contrib.formtools.wizard.FormWizard` class can live anywhere
-in your codebase, but convention is to put it in :file:`forms.py`.
+The next step is to create a
+:class:`django.contrib.formtools.wizard.FormWizard` subclass. As with your
+:class:`~django.forms.Form` classes, this :class:`FormWizard` class can live
+anywhere in your codebase, but convention is to put it in :file:`forms.py`.
The only requirement on this subclass is that it implement a
-:meth:`~django.contrib.formtools.wizard.FormWizard.done()` method,
-which specifies what should happen when the data for *every* form is submitted
-and validated. This method is passed two arguments:
+:meth:`~FormWizard.done()` method.
- * ``request`` -- an :class:`~django.http.HttpRequest` object
- * ``form_list`` -- a list of :mod:`django.forms`
- :class:`~django.forms.forms.Form` classes
+.. method:: FormWizard.done
+
+ This method specifies what should happen when the data for *every* form is
+ submitted and validated. This method is passed two arguments:
+
+ * ``request`` -- an :class:`~django.http.HttpRequest` object
+ * ``form_list`` -- a list of :class:`~django.forms.Form` classes
In this simplistic example, rather than perform any database operation, the
method simply renders a template of the validated data::
@@ -133,16 +131,16 @@ example::
return HttpResponseRedirect('/page-to-redirect-to-when-done/')
See the section `Advanced FormWizard methods`_ below to learn about more
-:class:`~django.contrib.formtools.wizard.FormWizard` hooks.
+:class:`FormWizard` hooks.
Creating templates for the forms
================================
Next, you'll need to create a template that renders the wizard's forms. By
default, every form uses a template called :file:`forms/wizard.html`. (You can
-change this template name by overriding
-:meth:`~django.contrib.formtools.wizard..get_template()`, which is documented
-below. This hook also allows you to use a different template for each form.)
+change this template name by overriding :meth:`~FormWizard.get_template()`,
+which is documented below. This hook also allows you to use a different
+template for each form.)
This template expects the following context:
@@ -150,24 +148,20 @@ This template expects the following context:
* ``step0`` -- The current step (zero-based).
* ``step`` -- The current step (one-based).
* ``step_count`` -- The total number of steps.
- * ``form`` -- The :class:`~django.forms.forms.Form` instance for the
- current step (either empty or with errors).
+ * ``form`` -- The :class:`~django.forms.Form` instance for the current step
+ (either empty or with errors).
* ``previous_fields`` -- A string representing every previous data field,
plus hashes for completed forms, all in the form of hidden fields. Note
- that you'll need to run this through the
- :meth:`~django.template.defaultfilters.safe` template filter, to prevent
- auto-escaping, because it's raw HTML.
+ that you'll need to run this through the :tfilter:`safe` template filter,
+ to prevent auto-escaping, because it's raw HTML.
-It will also be passed any objects in :data:`extra_context`, which is a
-dictionary you can specify that contains extra values to add to the context.
-You can specify it in two ways:
+You can supply extra context to this template in two ways:
- * Set the :attr:`~django.contrib.formtools.wizard.FormWizard.extra_context`
- attribute on your :class:`~django.contrib.formtools.wizard.FormWizard`
- subclass to a dictionary.
+ * Set the :attr:`~FormWizard.extra_context` attribute on your
+ :class:`FormWizard` subclass to a dictionary.
- * Pass :attr:`~django.contrib.formtools.wizard.FormWizard.extra_context`
- as extra parameters in the URLconf.
+ * Pass a dictionary as a parameter named ``extra_context`` to your wizard's
+ URL pattern in your URLconf. See :ref:`hooking-wizard-into-urlconf`.
Here's a full example template:
@@ -190,12 +184,13 @@ Here's a full example template:
Note that ``previous_fields``, ``step_field`` and ``step0`` are all required
for the wizard to work properly.
+.. _hooking-wizard-into-urlconf:
+
Hooking the wizard into a URLconf
=================================
-Finally, give your new :class:`~django.contrib.formtools.wizard.FormWizard`
-object a URL in ``urls.py``. The wizard takes a list of your form objects as
-arguments::
+Finally, give your new :class:`FormWizard` object a URL in ``urls.py``. The
+wizard takes a list of your :class:`~django.forms.Form` objects as arguments::
from django.conf.urls.defaults import *
from mysite.testapp.forms import ContactForm1, ContactForm2, ContactWizard
@@ -209,19 +204,18 @@ Advanced FormWizard methods
.. class:: FormWizard
- Aside from the :meth:`~django.contrib.formtools.wizard.FormWizard.done()`
- method, :class:`~django.contrib.formtools.wizard.FormWizard` offers a few
+ Aside from the :meth:`~done()` method, :class:`FormWizard` offers a few
advanced method hooks that let you customize how your wizard works.
- Some of these methods take an argument ``step``, which is a zero-based counter
- representing the current step of the wizard. (E.g., the first form is ``0`` and
- the second form is ``1``.)
+ Some of these methods take an argument ``step``, which is a zero-based
+ counter representing the current step of the wizard. (E.g., the first form
+ is ``0`` and the second form is ``1``.)
.. method:: FormWizard.prefix_for_step
- Given the step, returns a :class:`~django.forms.forms.Form` prefix to
- use. By default, this simply uses the step itself. For more, see the
- :ref:`form prefix documentation <form-prefix>`.
+ Given the step, returns a form prefix to use. By default, this simply uses
+ the step itself. For more, see the :ref:`form prefix documentation
+ <form-prefix>`.
Default implementation::
@@ -237,15 +231,18 @@ Advanced FormWizard methods
def render_hash_failure(self, request, step):
return self.render(self.get_form(step), request, step,
- context={'wizard_error': 'We apologize, but your form has expired. Please continue filling out the form from this page.'})
+ context={'wizard_error':
+ 'We apologize, but your form has expired. Please'
+ ' continue filling out the form from this page.'})
.. method:: FormWizard.security_hash
- Calculates the security hash for the given request object and :class:`~django.forms.forms.Form` instance.
+ Calculates the security hash for the given request object and
+ :class:`~django.forms.Form` instance.
By default, this uses an MD5 hash of the form data and your
- :setting:`SECRET_KEY` setting. It's rare that somebody would need to override
- this.
+ :setting:`SECRET_KEY` setting. It's rare that somebody would need to
+ override this.
Example::
@@ -254,8 +251,8 @@ Advanced FormWizard methods
.. method:: FormWizard.parse_params
- A hook for saving state from the request object and ``args`` / ``kwargs`` that
- were captured from the URL by your URLconf.
+ A hook for saving state from the request object and ``args`` / ``kwargs``
+ that were captured from the URL by your URLconf.
By default, this does nothing.
@@ -275,26 +272,23 @@ Advanced FormWizard methods
def get_template(self, step):
return 'myapp/wizard_%s.html' % step
- If :meth:`~FormWizard.get_template` returns a list of strings, then the wizard will use the
- template system's :func:`~django.template.loader.select_template()`
- function,
- :ref:`explained in the template docs <ref-templates-api-the-python-api>`.
+ If :meth:`~FormWizard.get_template` returns a list of strings, then the
+ wizard will use the template system's
+ :func:`~django.template.loader.select_template` function.
This means the system will use the first template that exists on the
filesystem. For example::
def get_template(self, step):
return ['myapp/wizard_%s.html' % step, 'myapp/wizard.html']
- .. _explained in the template docs: ../templates_python/#the-python-api
-
.. method:: FormWizard.render_template
Renders the template for the given step, returning an
:class:`~django.http.HttpResponse` object.
- Override this method if you want to add a custom context, return a different
- MIME type, etc. If you only need to override the template name, use
- :meth:`~FormWizard.get_template` instead.
+ Override this method if you want to add a custom context, return a
+ different MIME type, etc. If you only need to override the template name,
+ use :meth:`~FormWizard.get_template` instead.
The template will be rendered with the context documented in the
"Creating templates for the forms" section above.
@@ -302,12 +296,12 @@ Advanced FormWizard methods
.. method:: FormWizard.process_step
Hook for modifying the wizard's internal state, given a fully validated
- :class:`~django.forms.forms.Form` object. The Form is guaranteed to
- have clean, valid data.
+ :class:`~django.forms.Form` object. The Form is guaranteed to have clean,
+ valid data.
- This method should *not* modify any of that data. Rather, it might want to set
- ``self.extra_context`` or dynamically alter ``self.form_list``, based on
- previously submitted forms.
+ This method should *not* modify any of that data. Rather, it might want to
+ set ``self.extra_context`` or dynamically alter ``self.form_list``, based
+ on previously submitted forms.
Note that this method is called every time a page is rendered for *all*
submitted steps.
diff --git a/docs/ref/contrib/index.txt b/docs/ref/contrib/index.txt
index 4f401d6836..2d15c25dfe 100644
--- a/docs/ref/contrib/index.txt
+++ b/docs/ref/contrib/index.txt
@@ -1,8 +1,8 @@
.. _ref-contrib-index:
-============================
-The "django.contrib" add-ons
-============================
+====================
+``contrib`` packages
+====================
Django aims to follow Python's `"batteries included" philosophy`_. It ships
with a variety of extra, optional tools that solve common Web-development
@@ -19,7 +19,7 @@ those packages have.
``'django.contrib.admin'``) to your ``INSTALLED_APPS`` setting and re-run
``manage.py syncdb``.
-.. _"batteries included" philosophy: http://docs.python.org/tut/node12.html#batteries-included
+.. _"batteries included" philosophy: http://docs.python.org/tutorial/stdlib.html#batteries-included
.. toctree::
:maxdepth: 1
@@ -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
=========
diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt
index d63d546efa..660b7c623b 100644
--- a/docs/ref/contrib/localflavor.txt
+++ b/docs/ref/contrib/localflavor.txt
@@ -61,6 +61,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Slovakia_
* `South Africa`_
* Spain_
+ * Sweden_
* Switzerland_
* `United Kingdom`_
* `United States of America`_
@@ -101,6 +102,7 @@ Here's an example of how to use them::
.. _Slovakia: `Slovakia (sk)`_
.. _South Africa: `South Africa (za)`_
.. _Spain: `Spain (es)`_
+.. _Sweden: `Sweden (se)`_
.. _Switzerland: `Switzerland (ch)`_
.. _United Kingdom: `United Kingdom (uk)`_
.. _United States of America: `United States of America (us)`_
@@ -166,7 +168,7 @@ Austria (``at``)
.. class:: at.forms.ATStateSelect
- A ``Select`` widget that uses a list of Austrian states as its choices.
+ A ``Select`` widget that uses a list of Austrian states as its choices.
.. class:: at.forms.ATSocialSecurityNumberField
@@ -516,7 +518,7 @@ Romania (``ro``)
.. class:: ro.forms.ROIBANField
- A form field that validates its input as a Romanian International Bank
+ A form field that validates its input as a Romanian International Bank
Account Number (IBAN). The valid format is ROXX-XXXX-XXXX-XXXX-XXXX-XXXX,
with or without hyphens.
@@ -596,6 +598,60 @@ Spain (``es``)
A ``Select`` widget that uses a list of Spanish regions as its choices.
+Sweden (``se``)
+===============
+
+.. class:: se.forms.SECountySelect
+
+ A Select form widget that uses a list of the Swedish counties (län) as its
+ choices.
+
+ The cleaned value is the official county code -- see
+ http://en.wikipedia.org/wiki/Counties_of_Sweden for a list.
+
+.. class:: se.forms.SEOrganisationNumber
+
+ A form field that validates input as a Swedish organisation number
+ (organisationsnummer).
+
+ It accepts the same input as SEPersonalIdentityField (for sole
+ proprietorships (enskild firma). However, co-ordination numbers are not
+ accepted.
+
+ It also accepts ordinary Swedish organisation numbers with the format
+ NNNNNNNNNN.
+
+ The return value will be YYYYMMDDXXXX for sole proprietors, and NNNNNNNNNN
+ for other organisations.
+
+.. class:: se.forms.SEPersonalIdentityNumber
+
+ A form field that validates input as a Swedish personal identity number
+ (personnummer).
+
+ The correct formats are YYYYMMDD-XXXX, YYYYMMDDXXXX, YYMMDD-XXXX,
+ YYMMDDXXXX and YYMMDD+XXXX.
+
+ A \+ indicates that the person is older than 100 years, which will be taken
+ into consideration when the date is validated.
+
+ The checksum will be calculated and checked. The birth date is checked
+ to be a valid date.
+
+ By default, co-ordination numbers (samordningsnummer) will be accepted. To
+ only allow real personal identity numbers, pass the keyword argument
+ coordination_number=False to the constructor.
+
+ The cleaned value will always have the format YYYYMMDDXXXX.
+
+.. class:: se.forms.SEPostalCodeField
+
+ A form field that validates input as a Swedish postal code (postnummer).
+ Valid codes consist of five digits (XXXXX). The number can optionally be
+ formatted with a space after the third digit (XXX XX).
+
+ The cleaned value will never contain the space.
+
Switzerland (``ch``)
====================
@@ -627,7 +683,7 @@ United Kingdom (``uk``)
A form field that validates input as a UK postcode. The regular
expression used is sourced from the schema for British Standard BS7666
- address types at http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd.
+ address types at http://www.cabinetoffice.gov.uk/media/291293/bs7666-v2-0.xml.
.. class:: uk.forms.UKCountySelect
diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt
new file mode 100644
index 0000000000..20b509388c
--- /dev/null
+++ b/docs/ref/contrib/messages.txt
@@ -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/
diff --git a/docs/ref/contrib/sitemaps.txt b/docs/ref/contrib/sitemaps.txt
index e7cd224e3e..82a4d15cf4 100644
--- a/docs/ref/contrib/sitemaps.txt
+++ b/docs/ref/contrib/sitemaps.txt
@@ -36,7 +36,7 @@ To install the sitemap app, follow these steps:
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
setting.
- 2. Make sure ``'django.template.loaders.app_directories.load_template_source'``
+ 2. Make sure ``'django.template.loaders.app_directories.Loader'``
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default,
so you'll only need to change this if you've changed that setting.
@@ -45,7 +45,7 @@ To install the sitemap app, follow these steps:
(Note: The sitemap application doesn't install any database tables. The only
reason it needs to go into :setting:`INSTALLED_APPS` is so that the
-:func:`~django.template.loaders.app_directories.load_template_source` template
+:func:`~django.template.loaders.app_directories.Loader` template
loader can find the default templates.)
Initialization
diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt
index cb9c22b8bd..c27666303c 100644
--- a/docs/ref/contrib/syndication.txt
+++ b/docs/ref/contrib/syndication.txt
@@ -940,7 +940,7 @@ attributes. Thus, you can subclass the appropriate feed generator class
(``Atom1Feed`` or ``Rss201rev2Feed``) and extend these callbacks. They are:
.. _georss: http://georss.org/
-.. _itunes podcast format: http://www.apple.com/itunes/store/podcaststechspecs.html
+.. _itunes podcast format: http://www.apple.com/itunes/podcasts/specs.html
``SyndicationFeed.root_attributes(self, )``
Return a ``dict`` of attributes to add to the root feed element
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index fc58dbaf47..df8c64c97e 100644
--- a/docs/ref/databases.txt
+++ b/docs/ref/databases.txt
@@ -1,8 +1,8 @@
.. _ref-databases:
-===============================
-Notes about supported databases
-===============================
+=========
+Databases
+=========
Django attempts to support as many features as possible on all database
backends. However, not all database backends are alike, and we've had to make
@@ -44,18 +44,20 @@ Autocommit mode
.. versionadded:: 1.1
-If your application is particularly read-heavy and doesn't make many database
-writes, the overhead of a constantly open transaction can sometimes be
-noticeable. For those situations, if you're using the ``postgresql_psycopg2``
-backend, you can configure Django to use *"autocommit"* behavior for the
-connection, meaning that each database operation will normally be in its own
-transaction, rather than having the transaction extend over multiple
-operations. In this case, you can still manually start a transaction if you're
-doing something that requires consistency across multiple database operations.
-The autocommit behavior is enabled by setting the ``autocommit`` key in the
-:setting:`DATABASE_OPTIONS` setting::
+If your application is particularly read-heavy and doesn't make many
+database writes, the overhead of a constantly open transaction can
+sometimes be noticeable. For those situations, if you're using the
+``postgresql_psycopg2`` backend, you can configure Django to use
+*"autocommit"* behavior for the connection, meaning that each database
+operation will normally be in its own transaction, rather than having
+the transaction extend over multiple operations. In this case, you can
+still manually start a transaction if you're doing something that
+requires consistency across multiple database operations. The
+autocommit behavior is enabled by setting the ``autocommit`` key in
+the :setting:`OPTIONS` part of your database configuration in
+:setting:`DATABASES`::
- DATABASE_OPTIONS = {
+ OPTIONS = {
"autocommit": True,
}
@@ -67,11 +69,11 @@ objects are changed or none of them are.
.. admonition:: This is database-level autocommit
This functionality is not the same as the
- :ref:`topics-db-transactions-autocommit` decorator. That decorator is a
- Django-level implementation that commits automatically after data changing
- operations. The feature enabled using the :setting:`DATABASE_OPTIONS`
- settings provides autocommit behavior at the database adapter level. It
- commits after *every* operation.
+ :ref:`topics-db-transactions-autocommit` decorator. That decorator
+ is a Django-level implementation that commits automatically after
+ data changing operations. The feature enabled using the
+ :setting:`OPTIONS` option provides autocommit behavior at the
+ database adapter level. It commits after *every* operation.
If you are using this feature and performing an operation akin to delete or
updating that requires multiple operations, you are strongly recommended to
@@ -80,6 +82,21 @@ You should also audit your existing code for any instances of this behavior
before enabling this feature. It's faster, but it provides less automatic
protection for multi-call operations.
+Indexes for ``varchar`` and ``text`` columns
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. versionadded:: 1.1.2
+
+When specifying ``db_index=True`` on your model fields, Django typically
+outputs a single ``CREATE INDEX`` statement. However, if the database type
+for the field is either ``varchar`` or ``text`` (e.g., used by ``CharField``,
+``FileField``, and ``TextField``), then Django will create
+an additional index that uses an appropriate `PostgreSQL operator class`_
+for the column. The extra index is necessary to correctly perfrom
+lookups that use the ``LIKE`` operator in their SQL, as is done with the
+``contains`` and ``startswith`` lookup types.
+
+.. _PostgreSQL operator class: http://www.postgresql.org/docs/8.4/static/indexes-opclass.html
+
.. _mysql-notes:
MySQL notes
@@ -234,29 +251,33 @@ Refer to the :ref:`settings documentation <ref-settings>`.
Connection settings are used in this order:
- 1. :setting:`DATABASE_OPTIONS`.
- 2. :setting:`DATABASE_NAME`, :setting:`DATABASE_USER`,
- :setting:`DATABASE_PASSWORD`, :setting:`DATABASE_HOST`,
- :setting:`DATABASE_PORT`
+ 1. :setting:`OPTIONS`.
+ 2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
+ :setting:`HOST`, :setting:`PORT`
3. MySQL option files.
-In other words, if you set the name of the database in ``DATABASE_OPTIONS``,
-this will take precedence over ``DATABASE_NAME``, which would override
+In other words, if you set the name of the database in ``OPTIONS``,
+this will take precedence over ``NAME``, which would override
anything in a `MySQL option file`_.
Here's a sample configuration which uses a MySQL option file::
# settings.py
- DATABASE_ENGINE = "mysql"
- DATABASE_OPTIONS = {
- 'read_default_file': '/path/to/my.cnf',
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql',
+ 'OPTIONS': {
+ 'read_default_file': '/path/to/my.cnf',
+ },
+ }
}
+
# my.cnf
[client]
- database = DATABASE_NAME
- user = DATABASE_USER
- password = DATABASE_PASSWORD
+ database = NAME
+ user = USER
+ password = PASSWORD
default-character-set = utf8
Several other MySQLdb connection options may be useful, such as ``ssl``,
@@ -287,7 +308,7 @@ storage engine, you have a couple of options.
* Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables::
- DATABASE_OPTIONS = {
+ OPTIONS = {
"init_command": "SET storage_engine=INNODB",
}
@@ -452,7 +473,7 @@ If you're getting this error, you can solve it by:
* Increase the default timeout value by setting the ``timeout`` database
option option::
- DATABASE_OPTIONS = {
+ OPTIONS = {
# ...
"timeout": 20,
# ...
@@ -505,25 +526,34 @@ Connecting to the database
Your Django settings.py file should look something like this for Oracle::
- DATABASE_ENGINE = 'oracle'
- DATABASE_NAME = 'xe'
- DATABASE_USER = 'a_user'
- DATABASE_PASSWORD = 'a_password'
- DATABASE_HOST = ''
- DATABASE_PORT = ''
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.oracle',
+ 'NAME': 'xe',
+ 'USER': 'a_user',
+ 'PASSWORD': 'a_password',
+ 'HOST': '',
+ 'PORT': '' ,
+ }
+ }
+
If you don't use a ``tnsnames.ora`` file or a similar naming method that
recognizes the SID ("xe" in this example), then fill in both
-:setting:`DATABASE_HOST` and :setting:`DATABASE_PORT` like so::
+``HOST`` and ``PORT`` like so::
- DATABASE_ENGINE = 'oracle'
- DATABASE_NAME = 'xe'
- DATABASE_USER = 'a_user'
- DATABASE_PASSWORD = 'a_password'
- DATABASE_HOST = 'dbprod01ned.mycompany.com'
- DATABASE_PORT = '1540'
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.oracle',
+ 'NAME': 'xe',
+ 'USER': 'a_user',
+ 'PASSWORD': 'a_password',
+ 'HOST': 'dbprod01ned.mycompany.com',
+ 'PORT': '1540',
+ }
+ }
-You should supply both :setting:`DATABASE_HOST` and :setting:`DATABASE_PORT`, or leave both
+You should supply both ``HOST`` and ``PORT``, or leave both
as empty strings.
Tablespace options
diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index 80e368286e..2cd879423c 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -121,6 +121,11 @@ createcachetable
Creates a cache table named ``tablename`` for use with the database cache
backend. See :ref:`topics-cache` for more information.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database
+onto which the cachetable will be installed.
+
createsuperuser
---------------
@@ -155,8 +160,8 @@ dbshell
.. django-admin:: dbshell
Runs the command-line client for the database engine specified in your
-``DATABASE_ENGINE`` setting, with the connection parameters specified in your
-``DATABASE_USER``, ``DATABASE_PASSWORD``, etc., settings.
+``ENGINE`` setting, with the connection parameters specified in your
+``USER``, ``PASSWORD``, etc., settings.
* For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` command-line client.
@@ -167,6 +172,12 @@ the program name (``psql``, ``mysql``, ``sqlite3``) will find the program in
the right place. There's no way to specify the location of the program
manually.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database
+onto which to open a shell.
+
+
diffsettings
------------
@@ -199,21 +210,6 @@ records to dump. If you're using a :ref:`custom manager <custom-managers>` as
the default manager and it filters some of the available records, not all of the
objects will be dumped.
-.. django-admin-option:: --exclude
-
-.. versionadded:: 1.0
-
-Exclude a specific application from the applications whose contents is
-output. For example, to specifically exclude the `auth` application from
-the output, you would call::
-
- django-admin.py dumpdata --exclude=auth
-
-If you want to exclude multiple applications, use multiple ``--exclude``
-directives::
-
- django-admin.py dumpdata --exclude=auth --exclude=contenttypes
-
.. django-admin-option:: --format <fmt>
By default, ``dumpdata`` will format its output in JSON, but you can use the
@@ -226,6 +222,11 @@ By default, ``dumpdata`` will output all data on a single line. This isn't
easy for humans to read, so you can use the ``--indent`` option to
pretty-print the output with a number of indentation spaces.
+.. versionadded:: 1.0
+
+The :djadminopt:`--exclude` option may be provided to prevent specific
+applications from being dumped.
+
.. versionadded:: 1.1
In addition to specifying application names, you can provide a list of
@@ -234,6 +235,21 @@ name to ``dumpdata``, the dumped output will be restricted to that model,
rather than the entire application. You can also mix application names and
model names.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database
+onto which the data will be loaded.
+
+.. django-admin-option:: --natural
+
+.. versionadded:: 1.2
+
+Use :ref:`natural keys <topics-serialization-natural-keys>` to represent
+any foreign key and many-to-many relationship with a model that provides
+a natural key definition. If you are dumping ``contrib.auth`` ``Permission``
+objects or ``contrib.contenttypes`` ``ContentType`` objects, you should
+probably be using this flag.
+
flush
-----
@@ -247,13 +263,19 @@ fixture will be re-installed.
The :djadminopt:`--noinput` option may be provided to suppress all user
prompts.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option may be used to specify the database
+to flush.
+
+
inspectdb
---------
.. django-admin:: inspectdb
Introspects the database tables in the database pointed-to by the
-``DATABASE_NAME`` setting and outputs a Django model module (a ``models.py``
+``NAME`` setting and outputs a Django model module (a ``models.py``
file) to standard output.
Use this if you have a legacy database with which you'd like to use Django.
@@ -290,6 +312,12 @@ needed.
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
only works in PostgreSQL and with certain types of MySQL tables.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option may be used to specify the
+database to introspect.
+
+
loaddata <fixture fixture ...>
------------------------------
@@ -297,6 +325,11 @@ loaddata <fixture fixture ...>
Searches for and loads the contents of the named fixture into the database.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database
+onto which the data will be loaded.
+
What's a "fixture"?
~~~~~~~~~~~~~~~~~~~
@@ -378,6 +411,37 @@ installation will be aborted, and any data installed in the call to
references in your data files - MySQL doesn't provide a mechanism to
defer checking of row constraints until a transaction is committed.
+Database-specific fixtures
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are in a multi-database setup, you may have fixture data that
+you want to load onto one database, but not onto another. In this
+situation, you can add database identifier into . If your
+:setting:`DATABASES` setting has a 'master' database defined, you can
+define the fixture ``mydata.master.json`` or
+``mydata.master.json.gz``. This fixture will only be loaded if you
+have specified that you want to load data onto the ``master``
+database.
+
+Excluding applications from loading
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+The :djadminopt:`--exclude` option may be provided to prevent specific
+applications from being loaded.
+
+For example, if you wanted to exclude models from ``django.contrib.auth``
+from being loaded into your database, you would call::
+
+ django-admin.py loaddata mydata.json --exclude auth
+
+This will look for for a JSON fixture called ``mydata`` in all the
+usual locations - including the ``fixtures`` directory of the
+``django.contrib.auth`` application. However, any fixture object that
+identifies itself as belonging to the ``auth`` application (e.g.,
+instance of ``auth.User``) would be ignored by loaddata.
+
makemessages
------------
@@ -439,6 +503,11 @@ Executes the equivalent of ``sqlreset`` for the given app name(s).
The :djadminopt:`--noinput` option may be provided to suppress all user
prompts.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the alias
+of the database to reset.
+
runfcgi [options]
-----------------
@@ -556,6 +625,11 @@ sql <appname appname ...>
Prints the CREATE TABLE SQL statements for the given app name(s).
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlall <appname appname ...>
----------------------------
@@ -566,6 +640,11 @@ Prints the CREATE TABLE and initial-data SQL statements for the given app name(s
Refer to the description of ``sqlcustom`` for an explanation of how to
specify initial data.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlclear <appname appname ...>
------------------------------
@@ -573,6 +652,11 @@ sqlclear <appname appname ...>
Prints the DROP TABLE SQL statements for the given app name(s).
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlcustom <appname appname ...>
-------------------------------
@@ -594,6 +678,11 @@ table modifications, or insert any SQL functions into the database.
Note that the order in which the SQL files are processed is undefined.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlflush
--------
@@ -602,6 +691,11 @@ sqlflush
Prints the SQL statements that would be executed for the :djadmin:`flush`
command.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlindexes <appname appname ...>
--------------------------------
@@ -609,6 +703,11 @@ sqlindexes <appname appname ...>
Prints the CREATE INDEX SQL statements for the given app name(s).
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlreset <appname appname ...>
------------------------------
@@ -616,6 +715,11 @@ sqlreset <appname appname ...>
Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s).
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
sqlsequencereset <appname appname ...>
--------------------------------------
@@ -629,6 +733,11 @@ number for automatically incremented fields.
Use this command to generate SQL which will fix cases where a sequence is out
of sync with its automatically incremented field data.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database for
+which to print the SQL.
+
startapp <appname>
------------------
@@ -685,9 +794,16 @@ with an appropriate extension (e.g. ``json`` or ``xml``). See the
documentation for ``loaddata`` for details on the specification of fixture
data files.
+--noinput
+~~~~~~~~~
The :djadminopt:`--noinput` option may be provided to suppress all user
prompts.
+.. versionadded:: 1.2
+
+The :djadminopt:`--database` option can be used to specify the database to
+synchronize.
+
test <app or test identifier>
-----------------------------
@@ -696,6 +812,14 @@ test <app or test identifier>
Runs tests for all installed models. See :ref:`topics-testing` for more
information.
+--failfast
+~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+Use the ``--failfast`` option to stop running tests and report the failure
+immediately after a test fails.
+
testserver <fixture fixture ...>
--------------------------------
@@ -829,6 +953,30 @@ Common options
The following options are not available on every commands, but they are
common to a number of commands.
+.. django-admin-option:: --database
+
+.. versionadded:: 1.2
+
+Used to specify the database on which a command will operate. If not
+specified, this option will default to an alias of ``default``.
+
+For example, to dump data from the database with the alias ``master``::
+
+ django-admin.py dumpdata --database=master
+
+.. django-admin-option:: --exclude
+
+Exclude a specific application from the applications whose contents is
+output. For example, to specifically exclude the `auth` application from
+the output of dumpdata, you would call::
+
+ django-admin.py dumpdata --exclude=auth
+
+If you want to exclude multiple applications, use multiple ``--exclude``
+directives::
+
+ django-admin.py dumpdata --exclude=auth --exclude=contenttypes
+
.. django-admin-option:: --locale
Use the ``--locale`` or ``-l`` option to specify the locale to process.
@@ -843,13 +991,92 @@ being executed as an unattended, automated script.
Extra niceties
==============
+.. _syntax-coloring:
+
Syntax coloring
---------------
-The ``django-admin.py`` / ``manage.py`` commands that output SQL to standard
-output will use pretty color-coded output if your terminal supports
-ANSI-colored output. It won't use the color codes if you're piping the
-command's output to another program.
+The ``django-admin.py`` / ``manage.py`` commands that output SQL to
+standard output will use pretty color-coded output if your terminal
+supports ANSI-colored output. It won't use the color codes if you're
+piping the command's output to another program.
+
+The colors used for syntax highlighting can be customized. Django
+ships with three color palettes:
+
+ * ``dark``, suited to terminals that show white text on a black
+ background. This is the default palette.
+
+ * ``light``, suited to terminals that show white text on a black
+ background.
+
+ * ``nocolor``, which disables syntax highlighting.
+
+You select a palette by setting a ``DJANGO_COLORS`` environment
+variable to specify the palette you want to use. For example, to
+specify the ``light`` palette under a Unix or OS/X BASH shell, you
+would run the following at a command prompt::
+
+ export DJANGO_COLORS="light"
+
+You can also customize the colors that are used. Django specifies a
+number of roles in which color is used:
+
+ * ``error`` - A major error.
+ * ``notice`` - A minor error.
+ * ``sql_field`` - The name of a model field in SQL.
+ * ``sql_coltype`` - The type of a model field in SQL.
+ * ``sql_keyword`` - A SQL keyword.
+ * ``sql_table`` - The name of a model in SQL.
+
+Each of these roles can be assigned a specific foreground and
+background color, from the following list:
+
+ * ``black``
+ * ``red``
+ * ``green``
+ * ``yellow``
+ * ``blue``
+ * ``magenta``
+ * ``cyan``
+ * ``white``
+
+Each of these colors can then be modified by using the following
+display options:
+
+ * ``bold``
+ * ``underscore``
+ * ``blink``
+ * ``reverse``
+ * ``conceal``
+
+A color specification follows one of the the following patterns:
+
+ * ``role=fg``
+ * ``role=fg/bg``
+ * ``role=fg,option,option``
+ * ``role=fg/bg,option,option``
+
+where ``role`` is the name of a valid color role, ``fg`` is the
+foreground color, ``bg`` is the background color and each ``option``
+is one of the color modifying options. Multiple color specifications
+are then separated by semicolon. For example::
+
+ export DJANGO_COLORS="error=yellow/blue,blink;notice=magenta"
+
+would specify that errors be displayed using blinking yellow on blue,
+and notices displayed using magenta. All other color roles would be
+left uncolored.
+
+Colors can also be specified by extending a base palette. If you put
+a palette name in a color specification, all the colors implied by that
+palette will be loaded. So::
+
+ export DJANGO_COLORS="light;error=yellow/blue,blink;notice=magenta"
+
+would specify the use of all the colors in the light color palette,
+*except* for the colors for errors and notices which would be
+overridden as specified.
Bash completion
---------------
diff --git a/docs/ref/files/index.txt b/docs/ref/files/index.txt
index bdc327b2d7..1d59d5fa23 100644
--- a/docs/ref/files/index.txt
+++ b/docs/ref/files/index.txt
@@ -1,13 +1,14 @@
.. _ref-files-index:
-File handling reference
-=======================
+=============
+File handling
+=============
.. module:: django.core.files
:synopsis: File handling and storage
.. toctree::
:maxdepth: 1
-
+
file
- storage \ No newline at end of file
+ storage
diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt
index 7a2341f69b..c313eb5c6b 100644
--- a/docs/ref/forms/api.txt
+++ b/docs/ref/forms/api.txt
@@ -4,6 +4,8 @@
The Forms API
=============
+.. module:: django.forms.forms
+
.. currentmodule:: django.forms
.. admonition:: About this document
@@ -25,6 +27,8 @@ A :class:`Form` instance is either **bound** to a set of data, or **unbound**.
* If it's **unbound**, it cannot do validation (because there's no data to
validate!), but it can still render the blank form as HTML.
+.. class:: Form
+
To create an unbound :class:`Form` instance, simply instantiate the class::
>>> f = ContactForm()
@@ -134,24 +138,25 @@ Dynamic initial values
.. attribute:: Form.initial
-Use ``initial`` to declare the initial value of form fields at runtime. For
-example, you might want to fill in a ``username`` field with the username of the
-current session.
+Use :attr:`~Form.initial` to declare the initial value of form fields at
+runtime. For example, you might want to fill in a ``username`` field with the
+username of the current session.
-To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
-if given, should be a dictionary mapping field names to initial values. Only
-include the fields for which you're specifying an initial value; it's not
-necessary to include every field in your form. For example::
+To accomplish this, use the :attr:`~Form.initial` argument to a :class:`Form`.
+This argument, if given, should be a dictionary mapping field names to initial
+values. Only include the fields for which you're specifying an initial value;
+it's not necessary to include every field in your form. For example::
>>> f = ContactForm(initial={'subject': 'Hi there!'})
These values are only displayed for unbound forms, and they're not used as
fallback values if a particular value isn't provided.
-Note that if a ``Field`` defines ``initial`` *and* you include ``initial`` when
-instantiating the ``Form``, then the latter ``initial`` will have precedence. In
-this example, ``initial`` is provided both at the field level and at the form
-instance level, and the latter gets precedence::
+Note that if a :class:`~django.forms.fields.Field` defines
+:attr:`~Form.initial` *and* you include ``initial`` when instantiating the
+``Form``, then the latter ``initial`` will have precedence. In this example,
+``initial`` is provided both at the field level and at the form instance level,
+and the latter gets precedence::
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='class')
@@ -166,20 +171,21 @@ instance level, and the latter gets precedence::
Accessing "clean" data
----------------------
-Each ``Field`` in a ``Form`` class is responsible not only for validating data,
-but also for "cleaning" it -- normalizing it to a consistent format. This is a
-nice feature, because it allows data for a particular field to be input in
+.. attribute:: Form.cleaned_data
+
+Each field in a :class:`Form` class is responsible not only for validating
+data, but also for "cleaning" it -- normalizing it to a consistent format. This
+is a nice feature, because it allows data for a particular field to be input in
a variety of ways, always resulting in consistent output.
-For example, ``DateField`` normalizes input into a Python ``datetime.date``
-object. Regardless of whether you pass it a string in the format
-``'1994-07-15'``, a ``datetime.date`` object or a number of other formats,
-``DateField`` will always normalize it to a ``datetime.date`` object as long as
-it's valid.
+For example, :class:`~django.forms.DateField` normalizes input into a
+Python ``datetime.date`` object. Regardless of whether you pass it a string in
+the format ``'1994-07-15'``, a ``datetime.date`` object, or a number of other
+formats, ``DateField`` will always normalize it to a ``datetime.date`` object
+as long as it's valid.
-Once you've created a ``Form`` instance with a set of data and validated it,
-you can access the clean data via the ``cleaned_data`` attribute of the ``Form``
-object::
+Once you've created a :class:`~Form` instance with a set of data and validated
+it, you can access the clean data via its ``cleaned_data`` attribute::
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
@@ -322,49 +328,86 @@ a form object, and each rendering method returns a Unicode object.
``as_p()``
~~~~~~~~~~
-``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
-containing one field::
+.. method:: Form.as_p
- >>> f = ContactForm()
- >>> f.as_p()
- u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
- >>> print f.as_p()
- <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
- <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
- <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
- <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
+ ``as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
+ containing one field::
+
+ >>> f = ContactForm()
+ >>> f.as_p()
+ u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
+ >>> print f.as_p()
+ <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
+ <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
+ <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
``as_ul()``
~~~~~~~~~~~
-``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
-``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
-so that you can specify any HTML attributes on the ``<ul>`` for flexibility::
+.. method:: Form.as_ul
- >>> f = ContactForm()
- >>> f.as_ul()
- u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
- >>> print f.as_ul()
- <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
- <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
- <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
+ ``as_ul()`` renders the form as a series of ``<li>`` tags, with each
+ ``<li>`` containing one field. It does *not* include the ``<ul>`` or
+ ``</ul>``, so that you can specify any HTML attributes on the ``<ul>`` for
+ flexibility::
+
+ >>> f = ContactForm()
+ >>> f.as_ul()
+ u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
+ >>> print f.as_ul()
+ <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
+ <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
+ <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
``as_table()``
~~~~~~~~~~~~~~
-Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
-exactly the same as ``print``. In fact, when you ``print`` a form object, it
-calls its ``as_table()`` method behind the scenes::
+.. method:: Form.as_table
- >>> f = ContactForm()
- >>> f.as_table()
- u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
+ Finally, ``as_table()`` outputs the form as an HTML ``<table>``. This is
+ exactly the same as ``print``. In fact, when you ``print`` a form object,
+ it calls its ``as_table()`` method behind the scenes::
+
+ >>> f = ContactForm()
+ >>> f.as_table()
+ u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
+ >>> print f.as_table()
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+
+Styling required or erroneous form rows
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+It's pretty common to style form rows and fields that are required or have
+errors. For example, you might want to present required form rows in bold and
+highlight errors in red.
+
+The :class:`Form` class has a couple of hooks you can use to add ``class``
+attributes to required rows or to rows with errors: simple set the
+:attr:`Form.error_css_class` and/or :attr:`Form.required_css_class`
+attributes::
+
+ class ContactForm(Form):
+ error_css_class = 'error'
+ required_css_class = 'required'
+
+ # ... and the rest of your fields here
+
+Once you've done that, rows will be given ``"error"`` and/or ``"required"``
+classes, as needed. The HTML will look something like::
+
+ >>> f = ContactForm(data)
>>> print f.as_table()
- <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
- <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
- <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+ <tr class="required"><th><label for="id_subject">Subject:</label> ...
+ <tr class="required"><th><label for="id_message">Message:</label> ...
+ <tr class="required error"><th><label for="id_sender">Sender:</label> ...
+ <tr><th><label for="id_cc_myself">Cc myself:<label> ...
.. _ref-forms-api-configuring-label:
diff --git a/docs/ref/forms/index.txt b/docs/ref/forms/index.txt
index a9e041c2a7..e310863c7a 100644
--- a/docs/ref/forms/index.txt
+++ b/docs/ref/forms/index.txt
@@ -1,5 +1,6 @@
.. _ref-forms-index:
+=====
Forms
=====
@@ -7,8 +8,8 @@ Detailed form API reference. For introductory material, see :ref:`topics-forms-i
.. toctree::
:maxdepth: 1
-
+
api
fields
widgets
- validation \ No newline at end of file
+ validation
diff --git a/docs/ref/generic-views.txt b/docs/ref/generic-views.txt
index 4752a705a0..af23506505 100644
--- a/docs/ref/generic-views.txt
+++ b/docs/ref/generic-views.txt
@@ -1088,4 +1088,3 @@ In addition to ``extra_context``, the template's context will be:
variable's name depends on the ``template_object_name`` parameter, which
is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
this variable's name will be ``foo``.
-
diff --git a/docs/ref/index.txt b/docs/ref/index.txt
index 6cc796d8e4..f1466c3496 100644
--- a/docs/ref/index.txt
+++ b/docs/ref/index.txt
@@ -1,5 +1,6 @@
.. _ref-index:
+=============
API Reference
=============
@@ -20,4 +21,3 @@ API Reference
signals
templates/index
unicode
-
diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt
index b0b26cc227..27a2d9a95a 100644
--- a/docs/ref/middleware.txt
+++ b/docs/ref/middleware.txt
@@ -1,8 +1,8 @@
.. _ref-middleware:
-=============================
-Built-in middleware reference
-=============================
+==========
+Middleware
+==========
.. module:: django.middleware
:synopsis: Django's built-in middleware classes.
@@ -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
------------------
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 0cb5be4b92..3c1106a217 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -299,6 +299,18 @@ according to available IDs. You usually won't need to use this directly; a
primary key field will automatically be added to your model if you don't specify
otherwise. See :ref:`automatic-primary-key-fields`.
+``BigIntegerField``
+-------------------
+
+.. versionadded:: 1.2
+
+.. class:: BigIntegerField([**options])
+
+A 64 bit integer, much like an :class:`IntegerField` except that it is
+guaranteed to fit numbers from -9223372036854775808 to 9223372036854775807. The
+admin represents this as an ``<input type="text">`` (a single-line input).
+
+
``BooleanField``
----------------
@@ -543,7 +555,7 @@ By default, :class:`FileField` instances are
created as ``varchar(100)`` columns in your database. As with other fields, you
can change the maximum length using the :attr:`~CharField.max_length` argument.
-.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
+.. _`strftime formatting`: http://docs.python.org/library/time.html#time.strftime
``FilePathField``
-----------------
diff --git a/docs/ref/models/index.txt b/docs/ref/models/index.txt
index 6918f335da..64b47b26cc 100644
--- a/docs/ref/models/index.txt
+++ b/docs/ref/models/index.txt
@@ -1,5 +1,6 @@
.. _ref-models-index:
+======
Models
======
diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt
index d74f8350e8..f3e7363e36 100644
--- a/docs/ref/models/options.txt
+++ b/docs/ref/models/options.txt
@@ -4,8 +4,9 @@
Model ``Meta`` options
======================
-This document explains all the possible :ref:`metadata options <meta-options>` that you can give your model in its internal
-``class Meta``.
+This document explains all the possible :ref:`metadata options
+<meta-options>` that you can give your model in its internal ``class
+Meta``.
Available ``Meta`` options
==========================
@@ -242,4 +243,3 @@ The plural name for the object::
verbose_name_plural = "stories"
If this isn't given, Django will use :attr:`~Options.verbose_name` + ``"s"``.
-
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index e685472cca..2dbe8f03b0 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -94,7 +94,7 @@ the query construction and is not part of the public API. However, it is safe
(and fully supported) to pickle and unpickle the attribute's contents as
described here.
-.. _pickle: http://docs.python.org/lib/module-pickle.html
+.. _pickle: http://docs.python.org/library/pickle.html
.. _queryset-api:
@@ -874,6 +874,24 @@ logically::
# existing set of fields).
Entry.objects.defer("body").only("headline", "body")
+``using(alias)``
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+This method is for controlling which database the ``QuerySet`` will be
+evaluated against if you are using more than one database. The only argument
+this method takes is the alias of a database, as defined in
+:setting:`DATABASES`.
+
+For example::
+
+ # queries the database with the 'default' alias.
+ >>> Entry.objects.all()
+
+ # queries the database with the 'backup' alias
+ >>> Entry.objects.using('backup')
+
QuerySet methods that do not return QuerySets
---------------------------------------------
@@ -1019,7 +1037,8 @@ Example::
``count()`` performs a ``SELECT COUNT(*)`` behind the scenes, so you should
always use ``count()`` rather than loading all of the record into Python
-objects and calling ``len()`` on the result.
+objects and calling ``len()`` on the result (unless you need to load the
+objects into memory anyway, in which case ``len()`` will be faster).
Depending on which database you're using (e.g. PostgreSQL vs. MySQL),
``count()`` may return a long integer instead of a normal Python integer. This
@@ -1112,6 +1131,20 @@ control the name of the aggregation value that is returned::
For an in-depth discussion of aggregation, see :ref:`the topic guide on
Aggregation <topics-db-aggregation>`.
+``exists()``
+~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+Returns ``True`` if the :class:`QuerySet` contains any results, and ``False``
+if not. This tries to perform the query in the simplest and fastest way
+possible, but it *does* execute nearly the same query. This means that calling
+:meth:`QuerySet.exists()` is faster than ``bool(some_query_set)``, but not by
+a large degree. If ``some_query_set`` has not yet been evaluated, but you know
+that it will be at some point, then using ``some_query_set.exists()`` will do
+more overall work (an additional query) than simply using
+``bool(some_query_set)``.
+
.. _field-lookups:
``exists()``
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 77d991bc1f..9dcf004149 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -298,9 +298,9 @@ a subclass of dictionary. Exceptions are outlined here:
>>> q = q.copy() # to make it mutable
>>> q.update({'a': '2'})
>>> q.getlist('a')
- ['1', '2']
+ [u'1', u'2']
>>> q['a'] # returns the last
- ['2']
+ [u'2']
.. method:: QueryDict.items()
@@ -309,7 +309,7 @@ a subclass of dictionary. Exceptions are outlined here:
>>> q = QueryDict('a=1&a=2&a=3')
>>> q.items()
- [('a', '3')]
+ [(u'a', u'3')]
.. method:: QueryDict.iteritems()
@@ -329,7 +329,7 @@ a subclass of dictionary. Exceptions are outlined here:
>>> q = QueryDict('a=1&a=2&a=3')
>>> q.values()
- ['3']
+ [u'3']
.. method:: QueryDict.itervalues()
@@ -369,7 +369,7 @@ In addition, ``QueryDict`` has the following methods:
>>> q = QueryDict('a=1&a=2&a=3')
>>> q.lists()
- [('a', ['1', '2', '3'])]
+ [(u'a', [u'1', u'2', u'3'])]
.. method:: QueryDict.urlencode()
@@ -598,4 +598,3 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
.. class:: HttpResponseServerError
Acts just like :class:`HttpResponse` but uses a 500 status code.
-
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 6e78030e8c..8cbc9ccc8f 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1,5 +1,13 @@
.. _ref-settings:
+========
+Settings
+========
+
+.. contents::
+ :local:
+ :depth: 1
+
Available settings
==================
@@ -189,30 +197,67 @@ where ``reason`` is a short message (intended for developers or logging, not for
end users) indicating the reason the request was rejected. See
:ref:`ref-contrib-csrf`.
-.. setting:: DATABASE_ENGINE
-DATABASE_ENGINE
----------------
+.. setting:: DATABASES
+
+DATABASES
+---------
+
+.. versionadded: 1.2
+
+Default: ``{}`` (Empty dictionary)
+
+A dictionary containing the settings for all databases to be used with
+Django. It is a nested dictionary who's contents maps database aliases
+to a dictionary containing the options for an individual database.
+
+The :setting:`DATABASES` setting must configure a ``default`` database;
+any number of additional databases may also be specified.
+
+The simplest possible settings file is for a single-database setup using
+SQLite. This can be configured using the following::
+
+ DATABASES = {
+ 'default': {
+ 'BACKEND': 'django.db.backends.sqlite3',
+ 'NAME': 'mydatabase'
+ }
+ }
+
+For other database backends, or more complex SQLite configurations, other options
+will be required. The following inner options are available.
+
+.. setting:: ENGINE
+
+ENGINE
+~~~~~~
Default: ``''`` (Empty string)
-The database backend to use. The built-in database backends are
-``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'sqlite3'``, and
-``'oracle'``.
+The database backend to use. The built-in database backends are:
+
+ * ``'django.db.backends.postgresql_psycopg2'``
+ * ``'django.db.backends.postgresql'``
+ * ``'django.db.backends.mysql'``
+ * ``'django.db.backends.sqlite3'``
+ * ``'django.db.backends.oracle'``
You can use a database backend that doesn't ship with Django by setting
-``DATABASE_ENGINE`` to a fully-qualified path (i.e.
+``ENGINE`` to a fully-qualified path (i.e.
``mypackage.backends.whatever``). Writing a whole new database backend from
scratch is left as an exercise to the reader; see the other backends for
examples.
-.. versionadded:: 1.0
- Support for external database backends is new in 1.0.
+.. note::
+ Prior to Django 1.2, you could use a short version of the backend name
+ to reference the built-in database backends (e.g., you could use
+ ``'sqlite3'`` to refer to the SQLite backend). This format has been
+ deprecated, and will be removed in Django 1.4.
-.. setting:: DATABASE_HOST
+.. setting:: HOST
-DATABASE_HOST
--------------
+HOST
+~~~~
Default: ``''`` (Empty string)
@@ -222,7 +267,7 @@ localhost. Not used with SQLite.
If this value starts with a forward slash (``'/'``) and you're using MySQL,
MySQL will connect via a Unix socket to the specified socket. For example::
- DATABASE_HOST = '/var/run/mysql'
+ "HOST": '/var/run/mysql'
If you're using MySQL and this value *doesn't* start with a forward slash, then
this value is assumed to be the host.
@@ -232,10 +277,10 @@ for the connection, rather than a network connection to localhost. If you
explicitly need to use a TCP/IP connection on the local machine with
PostgreSQL, specify ``localhost`` here.
-.. setting:: DATABASE_NAME
+.. setting:: NAME
-DATABASE_NAME
--------------
+NAME
+~~~~
Default: ``''`` (Empty string)
@@ -243,44 +288,90 @@ The name of the database to use. For SQLite, it's the full path to the database
file. When specifying the path, always use forward slashes, even on Windows
(e.g. ``C:/homes/user/mysite/sqlite3.db``).
-.. setting:: DATABASE_OPTIONS
+.. setting:: OPTIONS
-DATABASE_OPTIONS
-----------------
+OPTIONS
+~~~~~~~
Default: ``{}`` (Empty dictionary)
Extra parameters to use when connecting to the database. Consult backend
module's document for available keywords.
-.. setting:: DATABASE_PASSWORD
+.. setting:: PASSWORD
-DATABASE_PASSWORD
------------------
+PASSWORD
+~~~~~~~~
Default: ``''`` (Empty string)
The password to use when connecting to the database. Not used with SQLite.
-.. setting:: DATABASE_PORT
+.. setting:: PORT
-DATABASE_PORT
--------------
+PORT
+~~~~
Default: ``''`` (Empty string)
The port to use when connecting to the database. An empty string means the
default port. Not used with SQLite.
-.. setting:: DATABASE_USER
+.. setting:: USER
-DATABASE_USER
--------------
+USER
+~~~~
Default: ``''`` (Empty string)
The username to use when connecting to the database. Not used with SQLite.
+.. setting:: TEST_CHARSET
+
+TEST_CHARSET
+~~~~~~~~~~~~
+
+Default: ``None``
+
+The character set encoding used to create the test database. The value of this
+string is passed directly through to the database, so its format is
+backend-specific.
+
+Supported for the PostgreSQL_ (``postgresql``, ``postgresql_psycopg2``) and
+MySQL_ (``mysql``) backends.
+
+.. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html
+.. _MySQL: http://dev.mysql.com/doc/refman/5.0/en/charset-database.html
+
+.. setting:: TEST_COLLATION
+
+TEST_COLLATION
+~~~~~~~~~~~~~~
+
+Default: ``None``
+
+The collation order to use when creating the test database. This value is
+passed directly to the backend, so its format is backend-specific.
+
+Only supported for the ``mysql`` backend (see the `MySQL manual`_ for details).
+
+.. _MySQL manual: MySQL_
+
+.. setting:: TEST_NAME
+
+TEST_NAME
+~~~~~~~~~
+
+Default: ``None``
+
+The name of database to use when running the test suite.
+
+If the default value (``None``) is used with the SQLite database engine, the
+tests will use a memory resident database. For all other database engines the
+test database will use the name ``'test_' + DATABASE_NAME``.
+
+See :ref:`topics-testing`.
+
.. setting:: DATE_FORMAT
DATE_FORMAT
@@ -288,12 +379,32 @@ DATE_FORMAT
Default: ``'N j, Y'`` (e.g. ``Feb. 4, 2003``)
-The default formatting to use for date fields on Django admin change-list
-pages -- and, possibly, by other parts of the system. See
-:ttag:`allowed date format strings <now>`.
+The default formatting to use for date fields in any part of the system.
+Note that if ``USE_L10N`` is set to ``True``, then locale format will
+be applied. See :ttag:`allowed date format strings <now>`.
+
+See also ``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``SHORT_DATE_FORMAT``.
-See also ``DATETIME_FORMAT``, ``TIME_FORMAT``, ``YEAR_MONTH_FORMAT``
-and ``MONTH_DAY_FORMAT``.
+.. setting:: DATE_INPUT_FORMATS
+
+DATE_INPUT_FORMATS
+------------------
+
+Default::
+
+ ('%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y',
+ '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y',
+ '%B %d, %Y', '%d %B %Y', '%d %B, %Y')
+
+A tuple of formats that will be accepted when inputting data on a date
+field. Formats will be tried in order, using the first valid.
+Note that these format strings are specified in Python's datetime_ module
+syntax, that is different from the one used by Django for formatting dates
+to be displayed.
+
+See also ``DATETIME_INPUT_FORMATS`` and ``TIME_INPUT_FORMATS``.
+
+.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior
.. setting:: DATETIME_FORMAT
@@ -302,12 +413,32 @@ DATETIME_FORMAT
Default: ``'N j, Y, P'`` (e.g. ``Feb. 4, 2003, 4 p.m.``)
-The default formatting to use for datetime fields on Django admin change-list
-pages -- and, possibly, by other parts of the system. See
-:ttag:`allowed date format strings <now>`.
+The default formatting to use for datetime fields in any part of the system.
+Note that if ``USE_L10N`` is set to ``True``, then locale format will
+be applied. See :ttag:`allowed date format strings <now>`.
+
+See also ``DATE_FORMAT``, ``TIME_FORMAT`` and ``SHORT_DATETIME_FORMAT``.
-See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``,
-``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``.
+.. setting:: DATETIME_INPUT_FORMATS
+
+DATETIME_INPUT_FORMATS
+----------------------
+
+Default::
+
+ ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d',
+ '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M', '%m/%d/%Y',
+ '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M', '%m/%d/%y')
+
+A tuple of formats that will be accepted when inputting data on a datetime
+field. Formats will be tried in order, using the first valid.
+Note that these format strings are specified in Python's datetime_ module
+syntax, that is different from the one used by Django for formatting dates
+to be displayed.
+
+See also ``DATE_INPUT_FORMATS`` and ``TIME_INPUT_FORMATS``.
+
+.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior
.. setting:: DEBUG
@@ -347,6 +478,14 @@ will be suppressed, and exceptions will propagate upwards. This can
be useful for some test setups, and should never be used on a live
site.
+.. setting:: DECIMAL_SEPARATOR
+
+DECIMAL_SEPARATOR
+-----------------
+
+Default: ``'.'`` (Dot)
+
+Default decimal separator used when formatting decimal numbers.
.. setting:: DEFAULT_CHARSET
@@ -594,7 +733,22 @@ system's standard umask.
get totally incorrect behavior.
-.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html
+.. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod
+
+.. setting:: FIRST_DAY_OF_WEEK
+
+FIRST_DAY_OF_WEEK
+-----------------
+
+Default: ``0`` (Sunday)
+
+Number representing the first day of the week. This is especially useful
+when displaying a calendar. This value is only used when not using
+format internationalization, or when a format cannot be found for the
+current locale.
+
+The value must be an integer from 0 to 6, where 0 means Sunday, 1 means
+Monday and so on.
.. setting:: FIXTURE_DIRS
@@ -617,6 +771,34 @@ environment variable in any HTTP request. This setting can be used to override
the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version
of the preferred value or not supplied at all.
+.. setting:: FORMAT_MODULE_PATH
+
+FORMAT_MODULE_PATH
+------------------
+
+Default: ``None``
+
+A full Python path to a Python package that contains format definitions for
+project locales. If not ``None``, Django will check for a ``formats.py``
+file, under the directory named as the current locale, and will use the
+formats defined on this file.
+
+For example, if ``FORMAT_MODULE_PATH`` is set to ``mysite.formats``, and
+current language is ``en`` (English), Django will expect a directory tree
+like::
+
+ mysite/
+ formats/
+ __init__.py
+ en/
+ __init__.py
+ formats.py
+
+Available formats are ``DATE_FORMAT``, ``TIME_FORMAT``, ``DATETIME_FORMAT``,
+``YEAR_MONTH_FORMAT``, ``MONTH_DAY_FORMAT``, ``SHORT_DATE_FORMAT``,
+``SHORT_DATETIME_FORMAT``, ``FIRST_DAY_OF_WEEK``, ``DECIMAL_SEPARATOR``,
+``THOUSAND_SEPARATOR`` and ``NUMBER_GROUPING``.
+
.. setting:: IGNORABLE_404_ENDS
IGNORABLE_404_ENDS
@@ -761,7 +943,7 @@ LOGIN_URL
Default: ``'/accounts/login/'``
-The URL where requests are redirected for login, specially when using the
+The URL where requests are redirected for login, especially when using the
:func:`~django.contrib.auth.decorators.login_required` decorator.
.. setting:: LOGOUT_URL
@@ -812,6 +994,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
------------------
@@ -820,10 +1039,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
@@ -843,6 +1068,21 @@ locales have different formats. For example, U.S. English would say
See :ttag:`allowed date format strings <now>`. See also ``DATE_FORMAT``,
``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``YEAR_MONTH_FORMAT``.
+.. setting:: NUMBER_GROUPING
+
+NUMBER_GROUPING
+----------------
+
+Default: ``0``
+
+Number of digits grouped together on the integer part of a number. Common use
+is to display a thousand separator. If this setting is ``0``, then, no grouping
+will be applied to the number. If this setting is greater than ``0`` then the
+setting ``THOUSAND_SEPARATOR`` will be used as the separator between those
+groups.
+
+See also ``THOUSAND_SEPARATOR``
+
.. setting:: PREPEND_WWW
PREPEND_WWW
@@ -1002,6 +1242,18 @@ See the :ref:`topics-http-sessions`.
.. setting:: SESSION_EXPIRE_AT_BROWSER_CLOSE
+SESSION_DB_ALIAS
+----------------
+
+.. versionadded:: 1.2
+
+Default: ``None``
+
+If you're using database-backed session storage, this selects the database
+alias that will be used to store session data. By default, Django will use
+the ``default`` database, but you can store session data on any database
+you choose.
+
SESSION_EXPIRE_AT_BROWSER_CLOSE
-------------------------------
@@ -1034,6 +1286,32 @@ Default: ``False``
Whether to save the session data on every request. See
:ref:`topics-http-sessions`.
+.. setting:: SHORT_DATE_FORMAT
+
+SHORT_DATE_FORMAT
+-----------------
+
+Default: ``m/d/Y`` (e.g. ``12/31/2003``)
+
+An available formatting that can be used for date fields on templates.
+Note that if ``USE_L10N`` is set to ``True``, then locale format will
+be applied. See :ttag:`allowed date format strings <now>`.
+
+See also ``DATE_FORMAT`` and ``SHORT_DATETIME_FORMAT``.
+
+.. setting:: SHORT_DATETIME_FORMAT
+
+SHORT_DATETIME_FORMAT
+---------------------
+
+Default: ``m/d/Y P`` (e.g. ``12/31/2003 4 p.m.``)
+
+An available formatting that can be used for datetime fields on templates.
+Note that if ``USE_L10N`` is set to ``True``, then locale format will
+be applied. See :ttag:`allowed date format strings <now>`.
+
+See also ``DATE_FORMAT`` and ``SHORT_DATETIME_FORMAT``.
+
.. setting:: SITE_ID
SITE_ID
@@ -1059,12 +1337,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
@@ -1101,11 +1385,14 @@ TEMPLATE_LOADERS
Default::
- ('django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source')
+ ('django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader')
-A tuple of callables (as strings) that know how to import templates from
-various sources. See :ref:`ref-templates-api`.
+A tuple of template loader classes, specified as strings. Each ``Loader`` class
+knows how to import templates from a particular sources. Optionally, a tuple can be
+used instead of a string. The first item in the tuple should be the ``Loader``'s
+module, subsequent items are passed to the ``Loader`` during initialization. See
+:ref:`ref-templates-api`.
.. setting:: TEMPLATE_STRING_IF_INVALID
@@ -1117,81 +1404,59 @@ Default: ``''`` (Empty string)
Output, as a string, that the template system should use for invalid (e.g.
misspelled) variables. See :ref:`invalid-template-variables`..
-.. setting:: TEST_DATABASE_CHARSET
-
-TEST_DATABASE_CHARSET
----------------------
-
-.. versionadded:: 1.0
-
-Default: ``None``
-
-The character set encoding used to create the test database. The value of this
-string is passed directly through to the database, so its format is
-backend-specific.
-
-Supported for the PostgreSQL_ (``postgresql``, ``postgresql_psycopg2``) and MySQL_ (``mysql``) backends.
-
-.. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html
-.. _MySQL: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
-
-.. setting:: TEST_DATABASE_COLLATION
-
-TEST_DATABASE_COLLATION
-------------------------
-
-.. versionadded:: 1.0
+.. setting:: TEST_RUNNER
-Default: ``None``
+TEST_RUNNER
+-----------
-The collation order to use when creating the test database. This value is
-passed directly to the backend, so its format is backend-specific.
+Default: ``'django.test.simple.run_tests'``
-Only supported for the ``mysql`` backend (see `section 10.3.2`_ of the MySQL
-manual for details).
+The name of the method to use for starting the test suite. See
+:ref:`topics-testing`.
-.. _section 10.3.2: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
+.. _Testing Django Applications: ../testing/
-.. setting:: TEST_DATABASE_NAME
+.. setting:: THOUSAND_SEPARATOR
-TEST_DATABASE_NAME
+THOUSAND_SEPARATOR
------------------
-Default: ``None``
+Default ``,`` (Comma)
-The name of database to use when running the test suite.
+Default thousand separator used when formatting numbers. This setting is
+used only when ``NUMBER_GROUPPING`` is set.
-If the default value (``None``) is used with the SQLite database engine, the
-tests will use a memory resident database. For all other database engines the
-test database will use the name ``'test_' + settings.DATABASE_NAME``.
+See also ``NUMBER_GROUPPING``, ``DECIMAL_SEPARATOR``
-See :ref:`topics-testing`.
-
-.. setting:: TEST_RUNNER
+.. setting:: TIME_FORMAT
-TEST_RUNNER
+TIME_FORMAT
-----------
-Default: ``'django.test.simple.run_tests'``
+Default: ``'P'`` (e.g. ``4 p.m.``)
-The name of the method to use for starting the test suite. See
-:ref:`topics-testing`.
+The default formatting to use for time fields in any part of the system.
+Note that if ``USE_L10N`` is set to ``True``, then locale format will
+be applied. See :ttag:`allowed date format strings <now>`.
-.. _Testing Django Applications: ../testing/
+See also ``DATE_FORMAT`` and ``DATETIME_FORMAT``.
-.. setting:: TIME_FORMAT
+.. setting:: TIME_INPUT_FORMATS
-TIME_FORMAT
------------
+TIME_INPUT_FORMATS
+------------------
-Default: ``'P'`` (e.g. ``4 p.m.``)
+Default: ``('%H:%M:%S', '%H:%M')``
+
+A tuple of formats that will be accepted when inputting data on a time
+field. Formats will be tried in order, using the first valid.
+Note that these format strings are specified in Python's datetime_ module
+syntax, that is different from the one used by Django for formatting dates
+to be displayed.
-The default formatting to use for time fields on Django admin change-list
-pages -- and, possibly, by other parts of the system. See
-:ttag:`allowed date format strings <now>`.
+See also ``DATE_INPUT_FORMATS`` and ``DATETIME_INPUT_FORMATS``.
-See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``,
-``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``.
+.. _datetime: http://docs.python.org/library/datetime.html#strftime-behavior
.. setting:: TIME_ZONE
@@ -1246,6 +1511,19 @@ A boolean that specifies whether to output the "Etag" header. This saves
bandwidth but slows down performance. This is only used if ``CommonMiddleware``
is installed (see :ref:`topics-http-middleware`).
+.. setting:: USE_L10N
+
+USE_L10N
+--------
+
+Default ``False``
+
+A boolean that specifies if data will be localized by default or not. If this
+is set to ``True``, e.g. Django will display numbers and dates using the
+format of the current locale.
+
+See also ``USE_I18N`` and ``LANGUAGE_CODE``
+
.. setting:: USE_I18N
USE_I18N
@@ -1258,6 +1536,22 @@ enabled. This provides an easy way to turn it off, for performance. If this is
set to ``False``, Django will make some optimizations so as not to load the
internationalization machinery.
+See also ``USE_L10N``
+
+.. setting:: USE_THOUSAND_SEPARATOR
+
+USE_THOUSAND_SEPARATOR
+----------------------
+
+Default ``False``
+
+A boolean that specifies wheter to display numbers using a thousand separator.
+If this is set to ``True``, Django will use values from ``THOUSAND_SEPARATOR``
+and ``NUMBER_GROUPING`` from current locale, to format the number.
+``USE_L10N`` must be set to ``True``, in order to format numbers.
+
+See also ``THOUSAND_SEPARATOR`` and ``NUMBER_GROUPING``.
+
.. setting:: YEAR_MONTH_FORMAT
YEAR_MONTH_FORMAT
@@ -1276,3 +1570,97 @@ Different locales have different formats. For example, U.S. English would say
See :ttag:`allowed date format strings <now>`. See also ``DATE_FORMAT``,
``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``MONTH_DAY_FORMAT``.
+
+Deprecated settings
+===================
+
+.. setting:: DATABASE_ENGINE
+
+DATABASE_ENGINE
+---------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`ENGINE` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_HOST
+
+DATABASE_HOST
+-------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`HOST` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_NAME
+
+DATABASE_NAME
+-------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`NAME` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_OPTIONS
+
+DATABASE_OPTIONS
+----------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`OPTIONS` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_PASSWORD
+
+DATABASE_PASSWORD
+-----------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`PASSWORD` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_PORT
+
+DATABASE_PORT
+-------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`PORT` in
+ :setting:`DATABASES`.
+
+.. setting:: DATABASE_USER
+
+DATABASE_USER
+-------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`USER` in
+ :setting:`DATABASES`.
+
+.. setting:: TEST_DATABASE_CHARSET
+
+TEST_DATABASE_CHARSET
+---------------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`TEST_CHARSET` in
+ :setting:`DATABASES`.
+
+.. setting:: TEST_DATABASE_COLLATION
+
+TEST_DATABASE_COLLATION
+-----------------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`TEST_COLLATION` in
+ :setting:`DATABASES`.
+
+.. setting:: TEST_DATABASE_NAME
+
+TEST_DATABASE_NAME
+------------------
+
+.. deprecated:: 1.2
+ This setting has been replaced by :setting:`TEST_NAME` in
+ :setting:`DATABASES`.
+
diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt
index cc203f1817..b54a895000 100644
--- a/docs/ref/signals.txt
+++ b/docs/ref/signals.txt
@@ -1,8 +1,8 @@
.. _ref-signals:
-=========================
-Built-in signal reference
-=========================
+=======
+Signals
+=======
A list of all the signals that Django sends.
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index 1b6eeb7014..120cab384b 100644
--- a/docs/ref/templates/api.txt
+++ b/docs/ref/templates/api.txt
@@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -477,12 +502,14 @@ The Python API
Django has two ways to load templates from files:
-``django.template.loader.get_template(template_name)``
+.. function:: django.template.loader.get_template(template_name)
+
``get_template`` returns the compiled template (a ``Template`` object) for
the template with the given name. If the template doesn't exist, it raises
``django.template.TemplateDoesNotExist``.
-``django.template.loader.select_template(template_name_list)``
+.. function:: django.template.loader.select_template(template_name_list)
+
``select_template`` is just like ``get_template``, except it takes a list
of template names. Of the list, it returns the first template that exists.
@@ -546,11 +573,11 @@ by editing your :setting:`TEMPLATE_LOADERS` setting. :setting:`TEMPLATE_LOADERS`
should be a tuple of strings, where each string represents a template loader.
Here are the template loaders that come with Django:
-``django.template.loaders.filesystem.load_template_source``
+``django.template.loaders.filesystem.Loader``
Loads templates from the filesystem, according to :setting:`TEMPLATE_DIRS`.
This loader is enabled by default.
-``django.template.loaders.app_directories.load_template_source``
+``django.template.loaders.app_directories.Loader``
Loads templates from Django apps on the filesystem. For each app in
:setting:`INSTALLED_APPS`, the loader looks for a ``templates``
subdirectory. If the directory exists, Django looks for templates in there.
@@ -574,12 +601,43 @@ Here are the template loaders that come with Django:
This loader is enabled by default.
-``django.template.loaders.eggs.load_template_source``
+``django.template.loaders.eggs.Loader``
Just like ``app_directories`` above, but it loads templates from Python
eggs rather than from the filesystem.
This loader is disabled by default.
+``django.template.loaders.cached.Loader``
+ By default, the templating system will read and compile your templates every
+ time they need to be rendered. While the Django templating system is quite
+ fast, the overhead from reading and compiling templates can add up.
+
+ The cached template loader is a class-based loader that you configure with
+ a list of other loaders that it should wrap. The wrapped loaders are used to
+ locate unknown templates when they are first encountered. The cached loader
+ then stores the compiled ``Template`` in memory. The cached ``Template``
+ instance is returned for subsequent requests to load the same template.
+
+ For example, to enable template caching with the ``filesystem`` and
+ ``app_directories`` template loaders you might use the following settings::
+
+ TEMPLATE_LOADERS = (
+ ('django.template.loaders.cached.Loader', (
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+ )),
+ )
+
+ .. note::
+ All of the built-in Django template tags are safe to use with the cached
+ loader, but if you're using custom template tags that come from third
+ party packages, or that you wrote yourself, you should ensure that the
+ ``Node`` implementation for each tag is thread-safe. For more
+ information, see
+ :ref:`template tag thread safety considerations<template_tag_thread_safety>`.
+
+ This loader is disabled by default.
+
Django uses the template loaders in order according to the
:setting:`TEMPLATE_LOADERS` setting. It uses each loader until a loader finds a
match.
@@ -642,3 +700,68 @@ settings you wish to specify. You might want to consider setting at least
and :setting:`TEMPLATE_DEBUG`. All available settings are described in the
:ref:`settings documentation <ref-settings>`, and any setting starting with
``TEMPLATE_`` is of obvious interest.
+
+.. _topic-template-alternate-language:
+
+Using an alternative template language
+======================================
+
+.. versionadded 1.2
+
+The Django ``Template`` and ``Loader`` classes implement a simple API for
+loading and rendering templates. By providing some simple wrapper classes that
+implement this API we can use third party template systems like `Jinja2
+<http://jinja.pocoo.org/2/>`_ or `Cheetah <http://www.cheetahtemplate.org/>`_. This
+allows us to use third-party template libraries without giving up useful Django
+features like the Django ``Context`` object and handy shortcuts like
+``render_to_response()``.
+
+The core component of the Django templating system is the ``Template`` class.
+This class has a very simple interface: it has a constructor that takes a single
+positional argument specifying the template string, and a ``render()`` method
+that takes a ``django.template.context.Context`` object and returns a string
+containing the rendered response.
+
+Suppose we're using a template language that defines a ``Template`` object with
+a ``render()`` method that takes a dictionary rather than a ``Context`` object.
+We can write a simple wrapper that implements the Django ``Template`` interface::
+
+ import some_template_language
+ class Template(some_template_language.Template):
+ def render(self, context):
+ # flatten the Django Context into a single dictionary.
+ context_dict = {}
+ for d in context.dicts:
+ context_dict.update(d)
+ return super(Template, self).render(context_dict)
+
+That's all that's required to make our fictional ``Template`` class compatible
+with the Django loading and rendering system!
+
+The next step is to write a ``Loader`` class that returns instances of our custom
+template class instead of the default ``django.template.Template``. Custom ``Loader``
+classes should inherit from ``django.template.loader.BaseLoader`` and override
+the ``load_template_source()`` method, which takes a ``template_name`` argument,
+loads the template from disk (or elsewhere), and returns a tuple:
+``(template_string, template_origin)``.
+
+The ``load_template()`` method of the ``Loader`` class retrieves the template
+string by calling ``load_template_source()``, instantiates a ``Template`` from
+the template source, and returns a tuple: ``(template, template_origin)``. Since
+this is the method that actually instantiates the ``Template``, we'll need to
+override it to use our custom template class instead. We can inherit from the
+builtin ``django.template.loaders.app_directories.Loader`` to take advantage of
+the ``load_template_source()`` method implemented there::
+
+ from django.template.loaders import app_directories
+ class Loader(app_directories.Loader):
+ is_usable = True
+
+ def load_template(self, template_name, template_dirs=None):
+ source, origin = self.load_template_source(template_name, template_dirs)
+ template = Template(source)
+ return template, origin
+
+Finally, we need to modify our project settings, telling Django to use our custom
+loader. Now we can write all of our templates in our alternative template
+language while continuing to use the rest of the Django templating system.
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 20591311be..fb8b847608 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -323,6 +323,9 @@ displayed by the ``{{ athlete_list|length }}`` variable.
As you can see, the ``if`` tag can take an optional ``{% else %}`` clause that
will be displayed if the test fails.
+Boolean operators
+^^^^^^^^^^^^^^^^^
+
``if`` tags may use ``and``, ``or`` or ``not`` to test a number of variables or
to negate a given variable::
@@ -348,24 +351,153 @@ to negate a given variable::
There are some athletes and absolutely no coaches.
{% endif %}
-``if`` tags don't allow ``and`` and ``or`` clauses within the same tag, because
-the order of logic would be ambiguous. For example, this is invalid::
+.. versionchanged:: 1.2
+
+Use of both ``and`` and ``or`` clauses within the same tag is allowed, with
+``and`` having higher precedence than ``or`` e.g.::
{% if athlete_list and coach_list or cheerleader_list %}
-If you need to combine ``and`` and ``or`` to do advanced logic, just use nested
-``if`` tags. For example::
+will be interpreted like:
- {% if athlete_list %}
- {% if coach_list or cheerleader_list %}
- We have athletes, and either coaches or cheerleaders!
- {% endif %}
+.. code-block:: python
+
+ if (athlete_list and coach_list) or cheerleader_list
+
+Use of actual brackets in the ``if`` tag is invalid syntax. If you need them to
+indicate precedence, you should use nested ``if`` tags.
+
+.. versionadded:: 1.2
+
+
+``if`` tags may also use the operators ``==``, ``!=``, ``<``, ``>``,
+``<=``, ``>=`` and ``in`` which work as follows:
+
+
+``==`` operator
+^^^^^^^^^^^^^^^
+
+Equality. Example::
+
+ {% if somevar == "x" %}
+ This appears if variable somevar equals the string "x"
+ {% endif %}
+
+``!=`` operator
+^^^^^^^^^^^^^^^
+
+Inequality. Example::
+
+ {% if somevar != "x" %}
+ This appears if variable somevar does not equal the string "x",
+ or if somevar is not found in the context
+ {% endif %}
+
+``<`` operator
+^^^^^^^^^^^^^^
+
+Less than. Example::
+
+ {% if somevar < 100 %}
+ This appears if variable somevar is less than 100.
+ {% endif %}
+
+``>`` operator
+^^^^^^^^^^^^^^
+
+Greater than. Example::
+
+ {% if somevar > 0 %}
+ This appears if variable somevar is greater than 0.
+ {% endif %}
+
+``<=`` operator
+^^^^^^^^^^^^^^^
+
+Less than or equal to. Example::
+
+ {% if somevar <= 100 %}
+ This appears if variable somevar is less than 100 or equal to 100.
+ {% endif %}
+
+``>=`` operator
+^^^^^^^^^^^^^^^
+
+Greater than or equal to. Example::
+
+ {% if somevar >= 1 %}
+ This appears if variable somevar is greater than 1 or equal to 1.
{% endif %}
-Multiple uses of the same logical operator are fine, as long as you use the
-same operator. For example, this is valid::
+``in`` operator
+^^^^^^^^^^^^^^^
+
+Contained within. This operator is supported by many Python containers to test
+whether the given value is in the container. The following are some examples of
+how ``x in y`` will be interpreted::
+
+ {% if "bc" in "abcdef" %}
+ This appears since "bc" is a substring of "abcdef"
+ {% endif %}
+
+ {% if "hello" in greetings %}
+ If greetings is a list or set, one element of which is the string
+ "hello", this will appear.
+ {% endif %}
+
+ {% if user in users %}
+ If users is a QuerySet, this will appear if user is an
+ instance that belongs to the QuerySet.
+ {% endif %}
+
+
+The comparison operators cannot be 'chained' like in Python or in mathematical
+notation. For example, instead of using::
+
+ {% if a > b > c %} (WRONG)
+
+you should use::
+
+ {% if a > b and b > c %}
+
+
+Filters
+^^^^^^^
+
+You can also use filters in the ``if`` expression. For example::
+
+ {% if messages|length >= 100 %}
+ You have lots of messages today!
+ {% endif %}
+
+Complex expressions
+^^^^^^^^^^^^^^^^^^^
+
+All of the above can be combined to form complex expressions. For such
+expressions, it can be important to know how the operators are grouped when the
+expression is evaluated - that is, the precedence rules. The precedence of the
+operators, from lowest to highest, is as follows:
+
+ * ``or``
+ * ``and``
+ * ``not``
+ * ``in``
+ * ``==``, ``!=``, ``<``, ``>``,``<=``, ``>=``
+
+(This follows Python exactly). So, for example, the following complex if tag:
+
+ {% if a == b or c == d and e %}
+
+...will be interpreted as:
+
+.. code-block:: python
+
+ (a == b) or ((c == d) and e)
+
+If you need different precedence, you will need to use nested if tags. Sometimes
+that is better for clarity anyway, for the sake of those who do not know the
+precedence rules.
- {% if athlete_list or coach_list or parent_list or teacher_list %}
.. templatetag:: ifchanged
@@ -437,6 +569,9 @@ You cannot check for equality with Python objects such as ``True`` or
``False``. If you need to test if something is true or false, use the ``if``
tag instead.
+.. versionadded:: 1.2
+ An alternative to the ``ifequal`` tag is to use the :ttag:`if` tag and the ``==`` operator.
+
.. templatetag:: ifnotequal
ifnotequal
@@ -444,6 +579,9 @@ ifnotequal
Just like ``ifequal``, except it tests that the two arguments are not equal.
+.. versionadded:: 1.2
+ An alternative to the ``ifnotequal`` tag is to use the :ttag:`if` tag and the ``!=`` operator.
+
.. templatetag:: include
include
@@ -919,7 +1057,12 @@ If ``value`` is ``"String with spaces"``, the output will be ``"Stringwithspaces
date
~~~~
-Formats a date according to the given format (same as the `now`_ tag).
+Formats a date according to the given format.
+
+Given format can be one of the predefined ones ``DATE_FORMAT``,
+``DATETIME_FORMAT``, ``SHORT_DATE_FORMAT`` or ``SHORT_DATETIME_FORMAT``,
+or a custom format, same as the `now`_ tag. Note that predefined formats may
+vary depending on the current locale.
For example::
@@ -934,7 +1077,7 @@ When used without a format string::
{{ value|date }}
...the formatting string defined in the :setting:`DATE_FORMAT` setting will be
-used.
+used, without applying any localization.
.. templatefilter:: default
@@ -1482,7 +1625,11 @@ output will be ``"Joel is a slug"``.
time
~~~~
-Formats a time according to the given format (same as the `now`_ tag).
+Formats a time according to the given format.
+
+Given format can be the predefined one ``TIME_FORMAT``, or a custom format,
+same as the `now`_ tag. Note that the predefined format is locale depending.
+
The time filter will only accept parameters in the format string that relate
to the time of day, not the date (for obvious reasons). If you need to
format a date, use the `date`_ filter.
@@ -1499,7 +1646,7 @@ When used without a format string::
{{ value|time }}
...the formatting string defined in the :setting:`TIME_FORMAT` setting will be
-used.
+used, without aplying any localization.
.. templatefilter:: timesince
diff --git a/docs/ref/templates/index.txt b/docs/ref/templates/index.txt
index d7bf99aa8c..6655b3da18 100644
--- a/docs/ref/templates/index.txt
+++ b/docs/ref/templates/index.txt
@@ -1,7 +1,8 @@
.. _ref-templates-index:
-Template reference
-==================
+=========
+Templates
+=========
Django's template engine provides a powerful mini-language for defining the
user-facing layer of your application, encouraging a clean separation of
@@ -17,4 +18,4 @@ an understanding of HTML; no knowledge of Python is required.
.. seealso::
For information on writing your own custom tags and filters, see
- :ref:`howto-custom-template-tags`. \ No newline at end of file
+ :ref:`howto-custom-template-tags`.
diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt
index c5851a2c6c..a6149119bf 100644
--- a/docs/ref/unicode.txt
+++ b/docs/ref/unicode.txt
@@ -1,8 +1,8 @@
.. _ref-unicode:
-======================
-Unicode data in Django
-======================
+============
+Unicode data
+============
.. versionadded:: 1.0
@@ -21,8 +21,8 @@ data. Normally, this means giving it an encoding of UTF-8 or UTF-16. If you use
a more restrictive encoding -- for example, latin1 (iso8859-1) -- you won't be
able to store certain characters in the database, and information will be lost.
- * MySQL users, refer to the `MySQL manual`_ (section 10.3.2 for MySQL 5.1) for
- details on how to set or alter the database character set encoding.
+ * MySQL users, refer to the `MySQL manual`_ (section 9.1.3.2 for MySQL 5.1)
+ for details on how to set or alter the database character set encoding.
* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 21.2.2 in
PostgreSQL 8) for details on creating databases with the correct encoding.
@@ -30,7 +30,7 @@ able to store certain characters in the database, and information will be lost.
* SQLite users, there is nothing you need to do. SQLite always uses UTF-8
for internal encoding.
-.. _MySQL manual: http://www.mysql.org/doc/refman/5.1/en/charset-database.html
+.. _MySQL manual: http://dev.mysql.com/doc/refman/5.1/en/charset-database.html
.. _PostgreSQL manual: http://www.postgresql.org/docs/8.2/static/multibyte.html#AEN24104
All of Django's database backends automatically convert Unicode strings into
diff --git a/docs/releases/0.96.txt b/docs/releases/0.96.txt
index 186a0e8da9..8d795acebd 100644
--- a/docs/releases/0.96.txt
+++ b/docs/releases/0.96.txt
@@ -96,7 +96,7 @@ support:
* The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to
emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for
other custom SQL -- views, stored procedures, etc.).
-
+
* The vestigial ``install`` command has been removed. Use ``syncdb``.
Backslash escaping changed
@@ -179,20 +179,20 @@ strings that referred to callables were allowed). This allows a much more
natural use of URLconfs. For example, this URLconf::
from django.conf.urls.defaults import *
-
- urlpatterns = patterns('',
+
+ urlpatterns = patterns('',
('^myview/$', 'mysite.myapp.views.myview')
)
-
+
can now be rewritten as::
from django.conf.urls.defaults import *
from mysite.myapp.views import myview
-
- urlpatterns = patterns('',
+
+ urlpatterns = patterns('',
('^myview/$', myview)
)
-
+
One useful application of this can be seen when using decorators; this
change allows you to apply decorators to views *in your
URLconf*. Thus, you can make a generic view require login very
@@ -202,17 +202,17 @@ easily::
from django.contrib.auth.decorators import login_required
from django.views.generic.list_detail import object_list
from mysite.myapp.models import MyModel
-
+
info = {
"queryset" : MyModel.objects.all(),
}
-
- urlpatterns = patterns('',
+
+ urlpatterns = patterns('',
('^myview/$', login_required(object_list), info)
)
Note that both syntaxes (strings and callables) are valid, and will continue to
-be valid for the foreseeable future.
+be valid for the foreseeable future.
The test framework
------------------
@@ -227,8 +227,8 @@ start of your tests. This makes testing with real data much easier.
See `the testing documentation`_ for the full details.
-.. _doctest: http://docs.python.org/lib/module-doctest.html
-.. _unittest: http://docs.python.org/lib/module-unittest.html
+.. _doctest: http://docs.python.org/library/doctest.html
+.. _unittest: http://docs.python.org/library/unittest.html
.. _the testing documentation: http://www.djangoproject.com/documentation/0.96/testing/
.. _serialization formats: http://www.djangoproject.com/documentation/0.96/serialization/
@@ -248,19 +248,19 @@ all their hard work:
* Russell Keith-Magee and Malcolm Tredinnick for their major code
contributions. This release wouldn't have been possible without them.
-
+
* Our new release manager, James Bennett, for his work in getting out
0.95.1, 0.96, and (hopefully) future release.
-
+
* Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill,
Michael Radziej, and Gary Wilson. They agreed to take on the monumental
task of wrangling our tickets into nicely cataloged submission. Figuring
out what to work on is now about a million times easier; thanks again,
guys.
-
+
* Everyone who submitted a bug report, patch or ticket comment. We can't
possibly thank everyone by name -- over 200 developers submitted patches
that went into 0.96 -- but everyone who's contributed to Django is listed
in AUTHORS_.
-
+
.. _AUTHORS: http://code.djangoproject.com/browser/django/trunk/AUTHORS
diff --git a/docs/releases/1.1-alpha-1.txt b/docs/releases/1.1-alpha-1.txt
index 8cd695ef2d..664c354561 100644
--- a/docs/releases/1.1-alpha-1.txt
+++ b/docs/releases/1.1-alpha-1.txt
@@ -85,13 +85,13 @@ Other new features and changes introduced since Django 1.0 include:
* The ``include()`` function in Django URLconf modules can now accept sequences
of URL patterns (generated by ``patterns()``) in addition to module names.
-* Instances of Django forms (see `the forms overview <topics-forms-index>`_ now
- have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
+* Instances of Django forms (see :ref:`the forms overview <topics-forms-index>`)
+ now have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
which return the list of hidden -- i.e., ``<input type="hidden">`` -- and
visible fields on the form, respectively.
-* The ``redirect_to`` generic view (see `the generic views documentation
- <ref-generic-views>`_) now accepts an additional keyword argument
+* The ``redirect_to`` generic view (see :ref:`the generic views documentation
+ <ref-generic-views>`) now accepts an additional keyword argument
``permanent``. If ``permanent`` is ``True``, the view will emit an HTTP
permanent redirect (status code 301). If ``False``, the view will emit an HTTP
temporary redirect (status code 302).
@@ -99,7 +99,8 @@ Other new features and changes introduced since Django 1.0 include:
* A new database lookup type -- ``week_day`` -- has been added for ``DateField``
and ``DateTimeField``. This type of lookup accepts a number between 1 (Sunday)
and 7 (Saturday), and returns objects where the field value matches that day
- of the week. See `the full list of lookup types <field-lookups>`_ for details.
+ of the week. See :ref:`the full list of lookup types <field-lookups>` for
+ details.
* The ``{% for %}`` tag in Django's template language now accepts an optional
``{% empty %}`` clause, to be displayed when ``{% for %}`` is asked to loop
@@ -150,7 +151,7 @@ interested in helping out with Django's development, feel free to join the
discussions there.
Django's online documentation also includes pointers on how to contribute to
-Django:
+Django:
* :ref:`How to contribute to Django <internals-contributing>`
diff --git a/docs/releases/1.1.txt b/docs/releases/1.1.txt
index c69a4de2e4..61d76df7b6 100644
--- a/docs/releases/1.1.txt
+++ b/docs/releases/1.1.txt
@@ -392,13 +392,13 @@ Other new features and changes introduced since Django 1.0 include:
* The ``include()`` function in Django URLconf modules can now accept sequences
of URL patterns (generated by ``patterns()``) in addition to module names.
-* Instances of Django forms (see `the forms overview <topics-forms-index>`_ now
- have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
+* Instances of Django forms (see :ref:`the forms overview <topics-forms-index>`)
+ now have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
which return the list of hidden -- i.e., ``<input type="hidden">`` -- and
visible fields on the form, respectively.
-* The ``redirect_to`` generic view (see `the generic views documentation
- <ref-generic-views>`_) now accepts an additional keyword argument
+* The ``redirect_to`` generic view (see :ref:`the generic views documentation
+ <ref-generic-views>`) now accepts an additional keyword argument
``permanent``. If ``permanent`` is ``True``, the view will emit an HTTP
permanent redirect (status code 301). If ``False``, the view will emit an HTTP
temporary redirect (status code 302).
@@ -406,7 +406,8 @@ Other new features and changes introduced since Django 1.0 include:
* A new database lookup type -- ``week_day`` -- has been added for ``DateField``
and ``DateTimeField``. This type of lookup accepts a number between 1 (Sunday)
and 7 (Saturday), and returns objects where the field value matches that day
- of the week. See `the full list of lookup types <field-lookups>`_ for details.
+ of the week. See :ref:`the full list of lookup types <field-lookups>` for
+ details.
* The ``{% for %}`` tag in Django's template language now accepts an optional
``{% empty %}`` clause, to be displayed when ``{% for %}`` is asked to loop
diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt
index 122b2f4927..8810963eaa 100644
--- a/docs/releases/1.2.txt
+++ b/docs/releases/1.2.txt
@@ -42,6 +42,15 @@ 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).
+:ttag:`if` tag changes
+----------------------
+
+Due to new features in the :ttag:`if` template tag, it no longer accepts 'and',
+'or' and 'not' as valid **variable** names. Previously that worked in some
+cases even though these strings were normally treated as keywords. Now, the
+keyword status is always enforced, and template code like ``{% if not %}`` or
+``{% if and %}`` will throw a TemplateSyntaxError.
+
``LazyObject``
--------------
@@ -67,6 +76,161 @@ changes:
__members__ = property(lambda self: self.__dir__())
+Specifying databases
+--------------------
+
+Prior to Django 1.1, Django used a number of settings to control access to a
+single database. Django 1.2 introduces support for multiple databases, and as
+a result, the way you define database settings has changed.
+
+Any existing Django settings file will continue to work as expected until
+Django 1.4. Old-style database settings will be automatically translated to
+the new-style format.
+
+In the old-style (pre 1.2) format, there were a number of
+``DATABASE_`` settings at the top level of your settings file. For
+example::
+
+ DATABASE_NAME = 'test_db'
+ DATABASE_BACKEND = 'postgresl_psycopg2'
+ DATABASE_USER = 'myusername'
+ DATABASE_PASSWORD = 's3krit'
+
+These settings are now contained inside a dictionary named
+:setting:`DATABASES`. Each item in the dictionary corresponds to a
+single database connection, with the name ``'default'`` describing the
+default database connection. The setting names have also been
+shortened to reflect the fact that they are stored in a dictionary.
+The sample settings given previously would now be stored using::
+
+ DATABASES = {
+ 'default': {
+ 'NAME': 'test_db',
+ 'BACKEND': 'django.db.backends.postgresl_psycopg2',
+ 'USER': 'myusername',
+ 'PASSWORD': 's3krit',
+ }
+ }
+
+This affects the following settings:
+
+ ========================================= ==========================
+ Old setting New Setting
+ ========================================= ==========================
+ :setting:`DATABASE_ENGINE` :setting:`ENGINE`
+ :setting:`DATABASE_HOST` :setting:`HOST`
+ :setting:`DATABASE_NAME` :setting:`NAME`
+ :setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
+ :setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
+ :setting:`DATABASE_PORT` :setting:`PORT`
+ :setting:`DATABASE_USER` :setting:`USER`
+ :setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
+ :setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
+ :setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
+ ========================================= ==========================
+
+These changes are also required if you have manually created a database
+connection using ``DatabaseWrapper()`` from your database backend of choice.
+
+In addition to the change in structure, Django 1.2 removes the special
+handling for the built-in database backends. All database backends
+must now be specified by a fully qualified module name (i.e.,
+``django.db.backends.postgresl_psycopg2``, rather than just
+``postgresql_psycopg2``).
+
+``__dict__`` on Model instances
+-------------------------------
+
+Historically, the ``__dict__`` attribute of a model instance has only contained
+attributes corresponding to the fields on a model.
+
+In order to support multiple database configurations, Django 1.2 has
+added a ``_state`` attribute to object instances. This attribute will
+appear in ``__dict__`` for a model instance. If your code relies on
+iterating over __dict__ to obtain a list of fields, you must now
+filter out ``_state`` attribute of out ``__dict__``.
+
+``get_db_prep_*()`` methods on Field
+------------------------------------
+
+Prior to v1.2, a custom field had the option of defining several
+functions to support conversion of Python values into
+database-compatible values. A custom field might look something like::
+
+ class CustomModelField(models.Field):
+ # ...
+
+ def get_db_prep_save(self, value):
+ # ...
+
+ def get_db_prep_value(self, value):
+ # ...
+
+ def get_db_prep_lookup(self, lookup_type, value):
+ # ...
+
+In 1.2, these three methods have undergone a change in prototype, and
+two extra methods have been introduced::
+
+ class CustomModelField(models.Field):
+ # ...
+
+ def get_prep_value(self, value):
+ # ...
+
+ def get_prep_lookup(self, lookup_type, value):
+ # ...
+
+ def get_db_prep_save(self, value, connection):
+ # ...
+
+ def get_db_prep_value(self, value, connection, prepared=False):
+ # ...
+
+ def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
+ # ...
+
+These changes are required to support multiple databases -
+``get_db_prep_*`` can no longer make any assumptions regarding the
+database for which it is preparing. The ``connection`` argument now
+provides the preparation methods with the specific connection for
+which the value is being prepared.
+
+The two new methods exist to differentiate general data preparation
+requirements, and requirements that are database-specific. The
+``prepared`` argument is used to indicate to the database preparation
+methods whether generic value preparation has been performed. If
+an unprepared (i.e., ``prepared=False``) value is provided to the
+``get_db_prep_*()`` calls, they should invoke the corresponding
+``get_prep_*()`` calls to perform generic data preparation.
+
+Conversion functions has been provided which will transparently
+convert functions adhering to the old prototype into functions
+compatible with the new prototype. However, this conversion function
+will be removed in Django 1.4, so you should upgrade your Field
+definitions to use the new prototype.
+
+If your ``get_db_prep_*()`` methods made no use of the database
+connection, you should be able to upgrade by renaming
+``get_db_prep_value()`` to ``get_prep_value()`` and
+``get_db_prep_lookup()`` to ``get_prep_lookup()`. If you require
+database specific conversions, then you will need to provide an
+implementation ``get_db_prep_*`` that uses the ``connection``
+argument to resolve database-specific values.
+
+Stateful template tags
+----------------------
+
+Template tags that store rendering state on the node itself may experience
+problems if they are used with the new :ref:`cached
+template loader<template-loaders>`.
+
+All of the built-in Django template tags are safe to use with the cached
+loader, but if you're using custom template tags that come from third
+party packages, or that you wrote yourself, you should ensure that the
+``Node`` implementation for each tag is thread-safe. For more
+information, see
+:ref:`template tag thread safety considerations<template_tag_thread_safety>`.
.. _deprecated-features-1.2:
@@ -122,6 +286,73 @@ additional arguments, those arguments can be passed to the
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.
+
+Date format helper functions
+----------------------------
+
+``django.utils.translation.get_date_formats()`` and
+``django.utils.translation.get_partial_date_formats()`` have been deprecated
+in favor of the appropriate calls to ``django.utils.formats.get_format()``
+which is locale aware when :setting:`USE_L10N` is set to ``True``, and falls
+back to default settings if set to ``False``.
+
+To get the different date formats, instead of writing::
+
+ from django.utils.translation import get_date_formats
+ date_format, datetime_format, time_format = get_date_formats()
+
+use::
+
+ from django.utils import formats
+
+ date_format = formats.get_format('DATE_FORMAT')
+ datetime_format = formats.get_format('DATETIME_FORMAT')
+ time_format = formats.get_format('TIME_FORMAT')
+
+or, when directly formatting a date value::
+
+ from django.utils import formats
+ value_formatted = formats.date_format(value, 'DATETIME_FORMAT')
+
+The same applies to the globals found in ``django.forms.fields``:
+
+ * ``DEFAULT_DATE_INPUT_FORMATS``
+ * ``DEFAULT_TIME_INPUT_FORMATS``
+ * ``DEFAULT_DATETIME_INPUT_FORMATS``
+
+Use ``django.utils.formats.get_format()`` to get the appropriate formats.
+
What's new in Django 1.2
========================
@@ -155,3 +386,116 @@ backend implementations that allow you to send e-mail to a
:ref:`memory<topic-email-memory-backend>` - you can even configure all
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
+------------------------------
+
+Django 1.2 adds the ability to use :ref:`more than one database
+<topics-db-multi-db>` in your Django project. Queries can be
+issued at a specific database with the `using()` method on
+querysets; individual objects can be saved to a specific database
+by providing a ``using`` argument when you save the instance.
+
+'Smart' if tag
+--------------
+
+The :ttag:`if` tag has been upgraded to be much more powerful. First, support
+for comparison operators has been added. No longer will you have to type:
+
+.. code-block:: html+django
+
+ {% ifnotequal a b %}
+ ...
+ {% endifnotequal %}
+
+...as you can now do:
+
+.. code-block:: html+django
+
+ {% if a != b %}
+ ...
+ {% endif %}
+
+The operators supported are ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=`` and
+``in``, all of which work like the Python operators, in addition to ``and``,
+``or`` and ``not`` which were already supported.
+
+Also, filters may now be used in the ``if`` expression. For example:
+
+.. code-block:: html+django
+
+ <div
+ {% if user.email|lower == message.recipient|lower %}
+ class="highlight"
+ {% endif %}
+ >{{ message }}</div>
+
+Template caching
+----------------
+
+In previous versions of Django, every time you rendered a template it
+would be reloaded from disk. In Django 1.2, you can use a :ref:`cached
+template loader <template-loaders>` to load templates once, then use a
+cached the result for every subsequent render. This can lead to a
+significant performance improvement if your templates are broken into
+lots of smaller subtemplates (using the ``{% extends %}`` or ``{%
+include %}`` tags).
+
+As a side effect, it is now much easier to support non-Django template
+languages. For more details, see the :ref:`notes on supporting
+non-Django template languages<topic-template-alternate-language>`.
+
+Natural keys in fixtures
+------------------------
+
+Fixtures can refer to remote objects using
+:ref:`topics-serialization-natural-keys`. This lookup scheme is an
+alternative to the normal primary-key based object references in a
+fixture, improving readability, and resolving problems referring to
+objects whose primary key value may not be predictable or known.
+
+``BigIntegerField``
+-------------------
+
+Models can now use a 64 bit :class:`~django.db.models.BigIntegerField` type.
+
+Fast Failure for Tests
+----------------------
+
+The ``test`` subcommand of ``django-admin.py``, and the ``runtests.py`` script
+used to run Django's own test suite, support a new ``--failfast`` option.
+When specified, this option causes the test runner to exit after
+encountering a failure instead of continuing with the test run.
+
+Improved localization
+---------------------
+
+Django's :ref:`internationalization framework <topics-i18n>` has been
+expanded by locale aware formatting and form processing. That means, if
+enabled, dates and numbers on templates will be displayed using the format
+specified for the current locale. Django will also use localized formats
+when parsing data in forms.
+See :ref:`Format localization <format-localization>` for more details.
+
+Added ``readonly_fields`` to ``ModelAdmin``
+-------------------------------------------
+
+:attr:`django.contrib.admin.ModelAdmin.readonly_fields` has been added to
+enable non-editable fields in add/change pages for models and inlines. Field
+and calculated values can be displayed along side editable fields.
+
+Customizable syntax highlighting
+--------------------------------
+
+You can now use the ``DJANGO_COLORS`` environment variable to modify
+or disable the colors used by ``django-admin.py`` to provide
+:ref:`syntax highlighting <syntax-coloring>`.
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index 33461a0858..8aae4f5e73 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -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
============
@@ -199,29 +202,50 @@ Methods
:meth:`~django.contrib.auth.models.User.set_unusable_password()` has
been called for this user.
- .. method:: models.User.get_group_permissions()
+ .. method:: models.User.get_group_permissions(obj=None)
Returns a list of permission strings that the user has, through his/her
groups.
- .. method:: models.User.get_all_permissions()
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, only returns the group permissions for
+ this specific object.
+
+ .. method:: models.User.get_all_permissions(obj=None)
Returns a list of permission strings that the user has, both through
group and user permissions.
- .. method:: models.User.has_perm(perm)
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, only returns the permissions for this
+ specific object.
+
+ .. method:: models.User.has_perm(perm, obj=None)
Returns ``True`` if the user has the specified permission, where perm is
- in the format ``"<app label>.<permission codename>"``.
- If the user is inactive, this method will always return ``False``.
+ in the format ``"<app label>.<permission codename>"``. (see
+ `permissions`_ section below). If the user is inactive, this method will
+ always return ``False``.
- .. method:: models.User.has_perms(perm_list)
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, this method won't check for a permission for
+ the model, but for this specific object.
+
+ .. method:: models.User.has_perms(perm_list, obj=None)
Returns ``True`` if the user has each of the specified permissions,
where each perm is in the format
``"<app label>.<permission codename>"``. If the user is inactive,
this method will always return ``False``.
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, this method won't check for permissions for
+ the model, but for the specific object.
+
.. method:: models.User.has_module_perms(package_name)
Returns ``True`` if the user has any permissions in the given package
@@ -1099,6 +1123,8 @@ generic view itself. For example::
def limited_object_detail(*args, **kwargs):
return object_detail(*args, **kwargs)
+.. _permissions:
+
Permissions
===========
@@ -1141,6 +1167,14 @@ models being installed at that time. Afterward, it will create default
permissions for new models each time you run :djadmin:`manage.py syncdb
<syncdb>`.
+Assuming you have an application with an
+:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
+to test for basic permissions you should use:
+
+ * add: ``user.has_perm('foo.add_bar')``
+ * change: ``user.has_perm('foo.change_bar')``
+ * delete: ``user.has_perm('foo.delete_bar')``
+
.. _custom-permissions:
Custom permissions
@@ -1289,6 +1323,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 +1373,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:
@@ -1510,3 +1552,24 @@ A full authorization implementation can be found in
the ``auth_permission`` table most of the time.
.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py
+
+Handling object permissions
+---------------------------
+
+Django's permission framework has a foundation for object permissions, though
+there is no implementation for it in the core. That means that checking for
+object permissions will always return ``False`` or an empty list (depending on
+the check performed).
+
+To enable object permissions in your own
+:ref:`authentication backend <ref-authentication-backends>` you'll just have
+to allow passing an ``obj`` parameter to the permission methods and set the
+``supports_objects_permissions`` class attribute to ``True``.
+
+A nonexistent ``supports_objects_permissions`` will raise a hidden
+``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this
+warning will be upgraded to a ``DeprecationWarning``, which will be displayed
+loudly. Additionally ``supports_objects_permissions`` will be set to ``False``.
+Django 1.4 will assume that every backend supports object permissions and
+won't check for the existence of ``supports_objects_permissions``, which
+means not supporting ``obj`` as a parameter will raise a ``TypeError``.
diff --git a/docs/topics/db/index.txt b/docs/topics/db/index.txt
index 949f4e87e9..bf918eba6b 100644
--- a/docs/topics/db/index.txt
+++ b/docs/topics/db/index.txt
@@ -16,3 +16,4 @@ model maps to a single database table.
managers
sql
transactions
+ multi-db
diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt
new file mode 100644
index 0000000000..3faa5bc0a6
--- /dev/null
+++ b/docs/topics/db/multi-db.txt
@@ -0,0 +1,269 @@
+.. _topics-db-multi-db:
+
+==================
+Multiple Databases
+==================
+
+.. versionadded:: 1.2
+
+This topic guide describes Django's support for interacting with multiple
+databases. Most of the rest of Django's documentation assumes you are
+interacting with a single database. If you want to interact with multiple
+databases, some additional steps must be taken.
+
+Defining your databases
+=======================
+
+The first step to using more than one database with Django is to tell
+Django about the database servers you'll be using. This is done using
+the :setting:`DATABASES` setting. This setting maps database aliases,
+which are a way to refer to a specific database throughout Django, to
+a dictionary of settings for that specific connection. The settings in
+the inner dictionaries are described fully in the :setting:`DATABASES`
+documentation.
+
+Regardless of how many databases you have, you *must* have a database
+named ``'default'``. Any additional databases you have can have
+whatever alias you choose.
+
+The following is an example ``settings.py`` snippet defining two
+databases - a default Postgres database, and a MySQL database called
+``users``:
+
+.. code-block:: python
+
+ DATABASES = {
+ 'default': {
+ 'NAME': 'app_data',
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
+ 'USER': 'postgres_user',
+ 'PASSWORD': 's3krit'
+ },
+ 'users': {
+ 'NAME': 'user_data'
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'priv4te'
+ }
+ }
+
+If you attempt to access a database that you haven't defined in your
+:setting:`DATABASES` setting then Django will raise a
+``django.db.utils.ConnectionDoesNotExist`` exception.
+
+Selecting a database for a ``QuerySet``
+=======================================
+
+It is possible to select the database for a ``QuerySet`` at any point
+during it's construction. To choose the database that a query will be
+preformed against simply call the ``using()`` method on the
+``QuerySet``. ``using()`` takes a single argument: the alias of the
+database on which you want to run the query. For example:
+
+.. code-block:: python
+
+ # This will run on the 'default' database...
+ >>> Author.objects.all()
+ # So will this...
+ >>> Author.objects.using('default').all()
+ # This will run on the 'other' database
+ >>> Author.objects.using('other').all()
+
+Select a database to save to
+============================
+
+To choose what database to save a model to, provide a ``using`` keyword
+argument to ``Model.save()``. For example if you had a user model that you
+wanted to save to the ``'legacy_users'`` database you would save the user
+by calling::
+
+ >>> user_obj.save(using='legacy_users')
+
+Moving an object from one database to another
+---------------------------------------------
+
+If you have saved an instance to one database, it might be tempting to use
+``save(using=...)`` as a way to migrate the instance to a new database. However,
+if you don't take appropriate steps, this could have some unexpected consequences.
+
+Consider the following example::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first') # (1)
+ # some other processing ...
+ >>> p.save(using='second') # (2)
+
+In statement 1, a new Person object is saved to the ``first``
+database. At this time, ``p`` doesn't have a primary key, so Django
+issues a SQL ``INSERT`` statement. This creates a primary key, and
+Django assigns that primary key to ``p``.
+
+When the save occurs in statement 2, ``p`` already has a primary key
+value, and Django will attempt to use that primary key on the new
+database. If the primary key value isn't in use in the ``second``
+database, then you won't have any problems -- the object will be
+copied to the new databse.
+
+However, if the primary key of ``p`` is already in use on the
+``second`` database, the existing object on the ``second`` database
+will be lost when ``p`` is saved.
+
+There are two ways to avoid this outcome. Firstly, you can clear the
+primary key of the instance. If an object has no primary key, Django
+will treat it as a new object, avoiding any loss of data on the
+``second`` database::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first')
+ # some other processing ...
+ >>> p.pk = None # Clear the PK
+ >>> p.save(using='second') # Write a completely new object
+
+Secondly, you can use the ``force_insert`` option to ``save()`` to ensure that
+Django does a SQL ``INSERT``::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first')
+ # some other processing ...
+ >>> p.save(using='second', force_insert=True)
+
+This will ensure that the person named ``Fred`` will have the same
+primary key on both databases. If that primary key is already in use
+when you try to save onto the ``second`` database, an error will be
+raised.
+
+Select a database to delete from
+================================
+
+By default, a call to delete an existing object will be executed on the
+same database that was used to retrieve the object in the first place::
+
+ >>> user_obj = User.objects.using('legacy_users').get(username='fred')
+ >>> user_obj.delete() # will delete from the `legacy_users` database
+
+If you want to specify the database from which a model will be
+deleted, you can use a ``using`` keyword argument to the
+``Model.delete()`` method. This argument is analogous to the ``using``
+keyword argument to ``save()``. For example if you were migrating a
+user from the ``'legacy_users'`` database to the ``'new_users'``
+database you might use the commands::
+
+ >>> user_obj.save(using='new_users')
+ >>> user_obj.delete(using='legacy_users')
+
+Using ``Managers`` with multiple databases
+==========================================
+
+When you call ``using()`` Django returns a ``QuerySet`` that will be
+evaluated against that database. However, sometimes you want to direct
+a manager to use a specific database chain ``using()``. If you call
+``using()``, you won't have access to any of the methods on the
+manager.
+
+To overcome this limitation, managers provide a ``db_manager()``
+method. This method returns a copy of the *manager* bound to that
+specific database. So, if you want to load an object using it's
+natural key (using the ``get_by_natural_key()`` method on the manager,
+you can call::
+
+ >>> Book.objects.db_manager("other").get_by_natural_key(...)
+
+If you are overriding ``get_query_set()`` on your manager you must be sure to
+either, call the method on the parent (using ``super()``), or do the
+appropriate handling of the ``_db`` attribute on the manager. For example if
+you wanted to return a custom ``QuerySet`` class from the ``get_query_set``
+method you could do this::
+
+ class MyManager(models.Manager):
+ ...
+ def get_query_set(self):
+ qs = CustomQuerySet(self.model)
+ if self._db is not None:
+ qs = qs.using(self._db)
+ return qs
+
+Exposing multiple databases in Django's admin interface
+=======================================================
+
+Django's admin doesn't have any explicit support for multiple
+databases. If you want to provide an admin interface for a model on a
+database other than ``default``, you need to write custom
+:class:`~django.contrib.admin.ModelAdmin` classes that will direct the
+admin to use a specific database for content.
+
+There are four methods that require customization on a ModelAdmin
+object::
+
+ class MultiDBModelAdmin(admin.ModelAdmin):
+ # A handy constant for the name of the alternate database
+ using = 'other'
+
+ def save_model(self, request, obj, form, change):
+ # Tell Django to save objects to the 'other' database
+ obj.save(using=self.using)
+
+ def queryset(self, request):
+ # Tell Django to look for objects on the 'other' database
+ return super(MultiDBModelAdmin, self).queryset(request).using(self.using)
+
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ForeignKey widgets using a query
+ # on the 'other' database
+ return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
+
+ def formfield_for_manytomany(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ManyToMany widgets using a query
+ # on the 'other' database
+ return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
+
+The implementation provided here implements a multi-db strategy where
+all objects of a given type are stored on a specific database (e.g.,
+all ``User`` objects are on the ``other`` database). If your usage of
+multi-db is more complex, your ModelAdmin will need to reflect that
+strategy.
+
+Inlines can be handled in a similar fashion -- they require just three
+customized methods::
+
+ class MultiDBTabularInline(admin.TabularInline):
+ using = 'other'
+
+ def queryset(self, request):
+ # Tell Django to look for inline objects on the 'other' database
+ return super(MultiDBTabularInline, self).queryset(request).using(self.using)
+
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ForeignKey widgets using a query
+ # on the 'other' database
+ return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
+
+ def formfield_for_manytomany(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ManyToMany widgets using a query
+ # on the 'other' database
+ return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
+
+Once you have written your model admin definitions, they can be
+registered with any Admin instance::
+
+ from django.contrib import admin
+
+ # Specialize the multi-db admin objects for use with specific models
+ class BookInline(MultiDBTabularInline):
+ model = Book
+
+ class PublisherAdmin(MultiDBModelAdmin):
+ inlines = [BookInline]
+
+ admin.site.register
+
+ admin.site.register(Author, MultiDBModelAdmin)
+ admin.site.register(Publisher, PublisherAdmin)
+
+ othersite = admin.Site('othersite')
+ othersite.register(Publisher, MultiDBModelAdmin)
+
+This example sets up two admin sites. On the first site, the
+``Author`` and ``Publisher`` objects are exposed; ``Publisher``
+objects have an tabular inline showing books published by that
+publisher. The second site exposes just publishers, without the
+inlines.
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
index 968ea7fbc8..a6ba3ebca7 100644
--- a/docs/topics/db/queries.txt
+++ b/docs/topics/db/queries.txt
@@ -327,7 +327,7 @@ translates (roughly) into the following SQL::
arguments whose names and values are evaluated at runtime. For more
information, see `Keyword Arguments`_ in the official Python tutorial.
- .. _`Keyword Arguments`: http://docs.python.org/tut/node6.html#SECTION006720000000000000000
+ .. _`Keyword Arguments`: http://docs.python.org/tutorial/controlflow.html#keyword-arguments
If you pass an invalid keyword argument, a lookup function will raise
``TypeError``.
@@ -1059,14 +1059,9 @@ Falling back to raw SQL
=======================
If you find yourself needing to write an SQL query that is too complex for
-Django's database-mapper to handle, you can fall back into raw-SQL statement
-mode.
-
-The preferred way to do this is by giving your model custom methods or custom
-manager methods that execute queries. Although there's nothing in Django that
-*requires* database queries to live in the model layer, this approach keeps all
-your data-access logic in one place, which is smart from an code-organization
-standpoint. For instructions, see :ref:`topics-db-sql`.
+Django's database-mapper to handle, you can fall back on writing SQL by hand.
+Django has a couple of options for writing raw SQL queries; see
+:ref:`topics-db-sql`.
Finally, it's important to note that the Django database layer is merely an
interface to your database. You can access your database via other tools,
diff --git a/docs/topics/db/sql.txt b/docs/topics/db/sql.txt
index 9c534709ca..075b9b27a3 100644
--- a/docs/topics/db/sql.txt
+++ b/docs/topics/db/sql.txt
@@ -1,10 +1,183 @@
.. _topics-db-sql:
+==========================
Performing raw SQL queries
==========================
-Feel free to write custom SQL statements in custom model methods and
-module-level methods. The object ``django.db.connection`` represents the
+.. currentmodule:: django.db.models
+
+When the :ref:`model query APIs <topics-db-queries>` don't go far enough, you
+can fall back to writing raw SQL. Django gives you two ways of performing raw
+SQL queries: you can use :meth:`Manager.raw()` to `perform raw queries and
+return model instances`__, or you can avoid the model layer entirely and
+`execute custom SQL directly`__.
+
+__ `performing raw queries`_
+__ `executing custom SQL directly`_
+
+Performing raw queries
+======================
+
+.. versionadded:: 1.2
+
+The ``raw()`` manager method can be used to perform raw SQL queries that
+return model instances:
+
+.. method:: Manager.raw(raw_query, params=None, translations=None)
+
+This method method takes a raw SQL query, executes it, and returns model
+instances.
+
+This is best illustrated with an example. Suppose you've got the following model::
+
+ class Person(models.Model):
+ first_name = models.CharField(...)
+ last_name = models.CharField(...)
+ birth_date = models.DateField(...)
+
+You could then execute custom SQL like so::
+
+ >>> Person.objects.raw('SELECT * from myapp_person')
+ [<Person: John Doe>, <Person: Jane Doe>, ...]
+
+.. admonition:: Model table names
+
+ Where'd the name of the ``Person`` table come from in that example?
+
+ By default, Django figures out a database table name by joining the
+ model's "app label" -- the name you used in ``manage.py startapp`` -- to
+ the model's class name, with an underscore between them. In the example
+ we've assumed that the ``Person`` model lives in an app named ``myapp``,
+ so its table would be ``myapp_person``.
+
+ For more details check out the documentation for the
+ :attr:`~Options.db_table` option, which also lets you manually set the
+ database table name.
+
+Of course, this example isn't very exciting -- it's exactly the same as
+running ``Person.objects.all()``. However, ``raw()`` has a bunch of other
+options that make it very powerful.
+
+Mapping query fields to model fields
+------------------------------------
+
+``raw()`` automatically maps fields in the query to fields on the model.
+
+The order of fields in your query doesn't matter. In other words, both
+of the following queries work identically::
+
+ >>> Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')
+ ...
+ >>> Person.objects.raw('SELECT last_name, birth_date, first_name, id FROM myapp_person')
+ ...
+
+Matching is done by name. This means that you can use SQL's ``AS`` clauses to
+map fields in the query to model fields. So if you had some other table that
+had ``Person`` data in it, you could easily map it into ``Person`` instances::
+
+ >>> Person.objects.raw('''SELECT first AS first_name,
+ ... last AS last_name,
+ ... bd AS birth_date,
+ ... pk as id,
+ ... FROM some_other_table)
+
+As long as the names match, the model instances will be created correctly.
+
+Alternatively, you can map fields in the query to model fields using the
+``translations`` argument to ``raw()``. This is a dictionary mapping names of
+fields in the query to names of fields on the model. For example, the above
+query could also be written::
+
+ >>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
+ >>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
+
+Deferring model fields
+----------------------
+
+Fields may also be left out::
+
+ >>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person'):
+
+The ``Person`` objects returned by this query will be :ref:`deferred
+<queryset-defer>` model instances. This means that the fields that are omitted
+from the query will be loaded on demand. For example::
+
+ >>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'):
+ ... print p.first_name, # This will be retrieved by the original query
+ ... print p.last_name # This will be retrieved on demand
+ ...
+ John Smith
+ Jane Jones
+
+From outward appearances, this looks like the query has retrieved both
+the first name and last name. However, this example actually issued 3
+queries. Only the first names were retrieved by the raw() query -- the
+last names were both retrieved on demand when they were printed.
+
+There is only one field that you can't leave out - the primary key
+field. Django uses the primary key to identify model instances, so it
+must always be included in a raw query. An ``InvalidQuery`` exception
+will be raised if you forget to include the primary key.
+
+Adding annotations
+------------------
+
+You can also execute queries containing fields that aren't defined on the
+model. For example, we could use `PostgreSQL's age() function`__ to get a list
+of people with their ages calculated by the database::
+
+ >>> people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
+ >>> for p in people:
+ ... print "%s is %s." % (p.first_name, p.age)
+ John is 37.
+ Jane is 42.
+ ...
+
+__ http://www.postgresql.org/docs/8.4/static/functions-datetime.html
+
+Passing parameters into ``raw()``
+---------------------------------
+
+If you need to perform parameterized queries, you can use the ``params``
+argument to ``raw()``::
+
+ >>> lname = 'Doe'
+ >>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
+
+``params`` is a list of parameters. You'll use ``%s`` placeholders in the
+query string (regardless of your database engine); they'll be replaced with
+parameters from the ``params`` list.
+
+.. warning::
+
+ **Do not use string formatting on raw queries!**
+
+ It's tempting to write the above query as::
+
+ >>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
+ >>> Person.objects.raw(query)
+
+ **Don't.**
+
+ Using the ``params`` list completely protects you from `SQL injection
+ attacks`__, a common exploit where attackers inject arbitrary SQL into
+ your database. If you use string interpolation, sooner or later you'll
+ fall victim to SQL injection. As long as you remember to always use the
+ ``params`` list you'll be protected.
+
+__ http://en.wikipedia.org/wiki/SQL_injection
+
+Executing custom SQL directly
+=============================
+
+Sometimes even :meth:`Manager.raw` isn't quite enough: you might need to
+perform queries that don't map cleanly to models, or directly execute
+``UPDATE``, ``INSERT``, or ``DELETE`` queries.
+
+In these cases, you can always access the database directly, routing around
+the model layer entirely.
+
+The object ``django.db.connection`` represents the
current database connection, and ``django.db.transaction`` represents the
current database transaction. To use the database connection, call
``connection.cursor()`` to get a cursor object. Then, call
@@ -15,7 +188,7 @@ changing operation, you should then call
to the database. If your query is purely a data retrieval operation, no commit
is required. For example::
- def my_custom_sql(self):
+ def my_custom_sql():
from django.db import connection, transaction
cursor = connection.cursor()
@@ -78,12 +251,4 @@ necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the
``"?"`` placeholder, which is used by the SQLite Python bindings. This is for
the sake of consistency and sanity.)
-An easier option?
------------------
-
-A final note: If all you want to do is a custom ``WHERE`` clause, you can just
-use the ``where``, ``tables`` and ``params`` arguments to the
-:ref:`extra clause <extra>` in the standard queryset API.
-
-.. _Python DB-API: http://www.python.org/peps/pep-0249.html
-
+.. _Python DB-API: http://www.python.org/dev/peps/pep-0249/
diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt
index b374609ab9..8902f6506c 100644
--- a/docs/topics/db/transactions.txt
+++ b/docs/topics/db/transactions.txt
@@ -56,7 +56,10 @@ Controlling transaction management in views
For most people, implicit request-based transactions work wonderfully. However,
if you need more fine-grained control over how transactions are managed, you
can use Python decorators to change the way transactions are handled by a
-particular view function.
+particular view function. All of the decorators take an option ``using``
+parameter which should be the alias for a database connection for which the
+behavior applies to. If no alias is specified then the ``"default"`` database
+is used.
.. note::
@@ -79,9 +82,14 @@ Example::
def viewfunc(request):
....
+ @transaction.autocommit(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
Within ``viewfunc()``, transactions will be committed as soon as you call
``model.save()``, ``model.delete()``, or any other function that writes to the
-database.
+database. ``viewfunc2()`` will have this same behavior, but for the
+``"my_other_database"`` connection.
``django.db.transaction.commit_on_success``
-------------------------------------------
@@ -95,6 +103,10 @@ all the work done in a function::
def viewfunc(request):
....
+ @transaction.commit_on_success(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
If the function returns successfully, then Django will commit all work done
within the function at that point. If the function raises an exception, though,
Django will roll back the transaction.
@@ -127,6 +139,10 @@ Manual transaction management looks like this::
else:
transaction.commit()
+ @transaction.commit_manually(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
.. admonition:: An important note to users of earlier Django releases:
The database ``connection.commit()`` and ``connection.rollback()`` methods
@@ -169,21 +185,25 @@ issue a rollback, the entire transaction is rolled back. Savepoints provide
the ability to perform a fine-grained rollback, rather than the full rollback
that would be performed by ``transaction.rollback()``.
+Each of these functions takes a ``using`` argument which should be the name of
+a database for which the behavior applies. If no ``using`` argument is
+provided then the ``"default"`` database is used.
+
Savepoints are controlled by three methods on the transaction object:
-.. method:: transaction.savepoint()
+.. method:: transaction.savepoint(using=None)
Creates a new savepoint. This marks a point in the transaction that
is known to be in a "good" state.
Returns the savepoint ID (sid).
-.. method:: transaction.savepoint_commit(sid)
+.. method:: transaction.savepoint_commit(sid, using=None)
Updates the savepoint to include any operations that have been performed
since the savepoint was created, or since the last commit.
-.. method:: transaction.savepoint_rollback(sid)
+.. method:: transaction.savepoint_rollback(sid, using=None)
Rolls the transaction back to the last point at which the savepoint was
committed.
diff --git a/docs/topics/files.txt b/docs/topics/files.txt
index 8e17db20fb..45aca5488a 100644
--- a/docs/topics/files.txt
+++ b/docs/topics/files.txt
@@ -55,7 +55,7 @@ Internally, Django uses a ``django.core.files.File`` any time it needs to
represent a file. This object is a thin wrapper around Python's `built-in file
object`_ with some Django-specific additions.
-.. _built-in file object: http://docs.python.org/lib/bltin-file-objects.html
+.. _built-in file object: http://docs.python.org/library/stdtypes.html#bltin-file-objects
Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
file attached to a model as above, or perhaps an uploaded file).
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index c5aa9c8a77..024479508a 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -46,6 +46,10 @@ the full list of conversions:
=============================== ========================================
``AutoField`` Not represented in the form
+ ``BigIntegerField`` ``IntegerField`` with ``min_value`` set
+ to -9223372036854775808 and ``max_value``
+ set to 9223372036854775807.
+
``BooleanField`` ``BooleanField``
``CharField`` ``CharField`` with ``max_length`` set to
@@ -108,6 +112,10 @@ the full list of conversions:
The ``FloatField`` form field and ``DecimalField`` model and form fields
are new in Django 1.0.
+.. versionadded:: 1.2
+ The ``BigIntegerField`` is new in Django 1.2.
+
+
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
types are special cases:
diff --git a/docs/topics/http/file-uploads.txt b/docs/topics/http/file-uploads.txt
index 428b390a2f..b3d520b3ee 100644
--- a/docs/topics/http/file-uploads.txt
+++ b/docs/topics/http/file-uploads.txt
@@ -30,7 +30,7 @@ is a dictionary containing a key for each ``FileField`` (or ``ImageField``, or
other ``FileField`` subclass) in the form. So the data from the above form would
be accessible as ``request.FILES['file']``.
-Note that ``request.FILES`` will only contain data if the request method was
+Note that ``request.FILES`` will only contain data if the request method was
``POST`` and the ``<form>`` that posted the request has the attribute
``enctype="multipart/form-data"``. Otherwise, ``request.FILES`` will be empty.
@@ -140,19 +140,19 @@ Three settings control Django's file upload behavior:
Defaults to your system's standard temporary directory (i.e. ``/tmp`` on
most Unix-like systems).
-
+
:setting:`FILE_UPLOAD_PERMISSIONS`
The numeric mode (i.e. ``0644``) to set newly uploaded files to. For
more information about what these modes mean, see the `documentation for
os.chmod`_
-
+
If this isn't given or is ``None``, you'll get operating-system
dependent behavior. On most platforms, temporary files will have a mode
of ``0600``, and files saved from memory will be saved using the
system's standard umask.
-
+
.. warning::
-
+
If you're not familiar with file modes, please note that the leading
``0`` is very important: it indicates an octal number, which is the
way that modes must be specified. If you try to use ``644``, you'll
@@ -173,7 +173,7 @@ Three settings control Django's file upload behavior:
Which means "try to upload to memory first, then fall back to temporary
files."
-.. _documentation for os.chmod: http://docs.python.org/lib/os-file-dir.html
+.. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod
``UploadedFile`` objects
========================
@@ -197,17 +197,17 @@ define the following methods/attributes:
``UploadedFile.temporary_file_path()``
Only files uploaded onto disk will have this method; it returns the full
path to the temporary uploaded file.
-
+
.. note::
Like regular Python files, you can read the file line-by-line simply by
iterating over the uploaded file:
-
+
.. code-block:: python
-
+
for line in uploadedfile:
do_something_with(line)
-
+
However, *unlike* standard Python files, :class:`UploadedFile` only
understands ``\n`` (also known as "Unix-style") line endings. If you know
that you need to handle uploaded files with different line endings, you'll
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 3b1429b440..cfe53c514b 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -24,14 +24,6 @@ To enable session functionality, do the following:
The default ``settings.py`` created by ``django-admin.py startproject`` has
``SessionMiddleware`` activated.
- * Add ``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting,
- and run ``manage.py syncdb`` to install the single database table
- that stores session data.
-
-.. versionchanged:: 1.0
- This step is optional if you're not using the database session backend;
- see `configuring the session engine`_.
-
If you don't want to use sessions, you might as well remove the
``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'``
from your ``INSTALLED_APPS``. It'll save you a small bit of overhead.
@@ -46,6 +38,22 @@ By default, Django stores sessions in your database (using the model
some setups it's faster to store session data elsewhere, so Django can be
configured to store session data on your filesystem or in your cache.
+Using database-backed sessions
+------------------------------
+
+If you want to use a database-backed session, you need to add
+``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting.
+
+If you want to store your session data on a database other than ``default``
+alias, you should set the :setting:`SESSION_DB_ALIAS` setting.
+
+Once you have configured your installation, run ``manage.py syncdb``
+to install the single database table that stores session data.
+
+.. versionadded:: 1.2
+ The :setting:`SESSION_DB_ALIAS` setting was added in Django 1.2. It
+ is not required in earlier versions.
+
Using cached sessions
---------------------
@@ -86,6 +94,9 @@ disregards persistence. In most cases, the ``cached_db`` backend will be fast
enough, but if you need that last bit of performance, and are willing to let
session data be expunged from time to time, the ``cache`` backend is for you.
+If you use the ``cached_db`` session backend, you also need to follow the
+configuration instructions for the `using database-backed sessions`_.
+
Using file-based sessions
-------------------------
@@ -97,6 +108,7 @@ to output from ``tempfile.gettempdir()``, most likely ``/tmp``) to control
where Django stores session files. Be sure to check that your Web server has
permissions to read and write to this location.
+
Using sessions in views
=======================
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index fd45e79876..0a5d04cdae 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -253,24 +253,30 @@ handler404
.. data:: handler404
-A string representing the full Python import path to the view that should be
-called if none of the URL patterns match.
+A callable, or a string representing the full Python import path to the view
+that should be called if none of the URL patterns match.
By default, this is ``'django.views.defaults.page_not_found'``. That default
value should suffice.
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
handler500
----------
.. data:: handler500
-A string representing the full Python import path to the view that should be
-called in case of server errors. Server errors happen when you have runtime
-errors in view code.
+A callable, or a string representing the full Python import path to the view
+that should be called in case of server errors. Server errors happen when you
+have runtime errors in view code.
By default, this is ``'django.views.defaults.server_error'``. That default
value should suffice.
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
include
-------
diff --git a/docs/topics/i18n.txt b/docs/topics/i18n.txt
index c5f4ab6481..70a8dd77cc 100644
--- a/docs/topics/i18n.txt
+++ b/docs/topics/i18n.txt
@@ -4,20 +4,20 @@
Internationalization
====================
-Django has full support for internationalization of text in code and templates.
-Here's how it works.
+Django has full support for internationalization of text in code and
+templates, and format localization of dates and numbers. Here's how it works.
Overview
========
The goal of internationalization is to allow a single Web application to offer
-its content and functionality in multiple languages.
+its content and functionality in multiple languages and locales.
-You, the Django developer, can accomplish this goal by adding a minimal amount
-of hooks to your Python code and templates. These hooks are called
-**translation strings**. They tell Django: "This text should be translated into
-the end user's language, if a translation for this text is available in that
-language."
+For text translation, you, the Django developer, can accomplish this goal by
+adding a minimal amount of hooks to your Python code and templates. These hooks
+are called **translation strings**. They tell Django: "This text should be
+translated into the end user's language, if a translation for this text is
+available in that language."
Django takes care of using these hooks to translate Web apps, on the fly,
according to users' language preferences.
@@ -29,6 +29,12 @@ Essentially, Django does two things:
* It uses these hooks to translate Web apps for particular users according
to their language preferences.
+For format localization, it's just necessary to set
+:setting:`USE_L10N = True <USE_L10N>` in your settings file. If
+:setting:`USE_L10N` is set to ``True``, Django will display
+numbers and dates in the format of the current locale. That includes field
+representation on templates, and allowed input formats on the admin.
+
If you don't need internationalization in your app
==================================================
@@ -225,15 +231,15 @@ Pluralization
Use the function ``django.utils.translation.ungettext()`` to specify pluralized
messages.
-``ungettext`` takes three arguments: the singular translation string, the plural
-translation string and the number of objects.
+``ungettext`` takes three arguments: the singular translation string, the
+plural translation string and the number of objects.
-This function is useful when your need you Django application to be localizable
+This function is useful when you need your Django application to be localizable
to languages where the number and complexity of `plural forms
<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
greater than the two forms used in English ('object' for the singular and
-'objects' for all the cases where ``count`` is different from zero, irrespective
-of its value.)
+'objects' for all the cases where ``count`` is different from zero,
+irrespective of its value).
For example::
@@ -276,8 +282,8 @@ cardinality of the elements at play.
.. note::
When using this technique, make sure you use a single name for every
- extrapolated variable included in the literal. In the example above note how
- we used the ``name`` Python variable in both translation strings. This
+ extrapolated variable included in the literal. In the example above note
+ how we used the ``name`` Python variable in both translation strings. This
example would fail::
from django.utils.translation import ungettext
@@ -355,8 +361,8 @@ To pluralize, specify both the singular and plural forms with the
{% endblocktrans %}
When you use the pluralization feature and bind additional values to local
-variables apart from the counter value that selects the translated literal to be
-used, have in mind that the ``blocktrans`` construct is internally converted
+variables apart from the counter value that selects the translated literal to
+be used, have in mind that the ``blocktrans`` construct is internally converted
to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext
variables <pluralization-var-notes>` apply.
@@ -375,8 +381,8 @@ Each ``RequestContext`` has access to three translation-specific variables:
left-to-right language, e.g.: English, French, German etc.
-If you don't use the ``RequestContext`` extension, you can get those values with
-three tags::
+If you don't use the ``RequestContext`` extension, you can get those values
+with three tags::
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
@@ -542,8 +548,6 @@ multiple times::
When `creating JavaScript translation catalogs`_ you need to use the special
'djangojs' domain, **not** ``-e js``.
-.. _create a JavaScript translation catalog: `Creating JavaScript translation catalogs`_
-
.. admonition:: No gettext?
If you don't have the ``gettext`` utilities installed, ``django-admin.py
@@ -584,8 +588,8 @@ A quick explanation:
out empty, so it's your responsibility to change it. Make sure you keep
the quotes around your translation.
* As a convenience, each message includes, in the form of a comment line
- prefixed with ``#`` and located above the ``msgid`` line, the filename and
- line number from which the translation string was gleaned.
+ prefixed with ``#`` and located above the ``msgid`` line, the filename
+ and line number from which the translation string was gleaned.
Long messages are a special case. There, the first string directly after the
``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
@@ -615,9 +619,9 @@ After you create your message file -- and each time you make changes to it --
you'll need to compile it into a more efficient form, for use by ``gettext``.
Do this with the ``django-admin.py compilemessages`` utility.
-This tool runs over all available ``.po`` files and creates ``.mo`` files, which
-are binary files optimized for use by ``gettext``. In the same directory from
-which you ran ``django-admin.py makemessages``, run ``django-admin.py
+This tool runs over all available ``.po`` files and creates ``.mo`` files,
+which are binary files optimized for use by ``gettext``. In the same directory
+from which you ran ``django-admin.py makemessages``, run ``django-admin.py
compilemessages`` like this::
django-admin.py compilemessages
@@ -818,9 +822,9 @@ message file. The choice is yours.
If you're using manually configured settings, as described
:ref:`settings-without-django-settings-module`, the ``locale`` directory in
the project directory will not be examined, since Django loses the ability
- to work out the location of the project directory. (Django normally uses the
- location of the settings file to determine this, and a settings file doesn't
- exist if you're manually configuring your settings.)
+ to work out the location of the project directory. (Django normally uses
+ the location of the settings file to determine this, and a settings file
+ doesn't exist if you're manually configuring your settings.)
All message file repositories are structured the same way. They are:
@@ -834,12 +838,13 @@ To create message files, you use the same ``django-admin.py makemessages``
tool as with the Django message files. You only need to be in the right place
-- in the directory where either the ``conf/locale`` (in case of the source
tree) or the ``locale/`` (in case of app messages or project messages)
-directory are located. And you use the same ``django-admin.py compilemessages``
-to produce the binary ``django.mo`` files that are used by ``gettext``.
+directory are located. And you use the same ``django-admin.py
+compilemessages`` to produce the binary ``django.mo`` files that are used by
+``gettext``.
-You can also run ``django-admin.py compilemessages --settings=path.to.settings``
-to make the compiler process all the directories in your ``LOCALE_PATHS``
-setting.
+You can also run ``django-admin.py compilemessages
+--settings=path.to.settings`` to make the compiler process all the directories
+in your ``LOCALE_PATHS`` setting.
Application message files are a bit complicated to discover -- they need the
``LocaleMiddleware``. If you don't use the middleware, only the Django message
@@ -1014,14 +1019,16 @@ Creating JavaScript translation catalogs
You create and update the translation catalogs the same way as the other
-Django translation catalogs -- with the django-admin.py makemessages tool. The
-only difference is you need to provide a ``-d djangojs`` parameter, like this::
+Django translation catalogs -- with the ``django-admin.py makemessages`` tool.
+The only difference is you need to provide a ``-d djangojs`` parameter, like
+this::
django-admin.py makemessages -d djangojs -l de
This would create or update the translation catalog for JavaScript for German.
-After updating translation catalogs, just run ``django-admin.py compilemessages``
-the same way as you do with normal Django translation catalogs.
+After updating translation catalogs, just run ``django-admin.py
+compilemessages`` the same way as you do with normal Django translation
+catalogs.
Specialties of Django translation
==================================
@@ -1042,10 +1049,11 @@ does translation:
``gettext`` on Windows
======================
-This is only needed for people who either want to extract message IDs or compile
-message files (``.po``). Translation work itself just involves editing existing
-files of this type, but if you want to create your own message files, or want to
-test or compile a changed message file, you will need the ``gettext`` utilities:
+This is only needed for people who either want to extract message IDs or
+compile message files (``.po``). Translation work itself just involves editing
+existing files of this type, but if you want to create your own message files,
+or want to test or compile a changed message file, you will need the
+``gettext`` utilities:
* Download the following zip files from the GNOME servers
http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
@@ -1074,3 +1082,53 @@ have been found to not support this command. Do not attempt to use Django
translation utilities with a ``gettext`` package if the command ``xgettext
--version`` entered at a Windows command prompt causes a popup window saying
"xgettext.exe has generated errors and will be closed by Windows".
+
+.. _format-localization:
+
+Format localization
+===================
+
+Django's formatting system is disabled by default. To enable it, it's necessay
+to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
+
+When using Django's formatting system, dates and numbers on templates will be
+displayed using the format specified for the current locale. Two users
+accessing the same content, but in different language, will see date and
+number fields formatted in different ways, depending on the format for their
+current locale.
+
+Django will also use localized formats when parsing data in forms. That means
+Django uses different formats for different locales when guessing the format
+used by the user when inputting data on forms. Note that Django uses different
+formats for displaying data, and for parsing it.
+
+Creating custom format files
+----------------------------
+
+Django provides format definitions for many locales, but sometimes you might
+want to create your own, because a format files doesn't exist for your locale,
+or because you want to overwrite some of the values.
+
+To use custom formats, first thing to do, is to specify the path where you'll
+place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH`
+setting to the the path (in the format ``'foo.bar.baz``) where format files
+will exists.
+
+Files are not placed directly in this directory, but in a directory named as
+the locale, and must be named ``formats.py``.
+
+To customize the English formats, a structure like this would be needed::
+
+ mysite/
+ formats/
+ __init__.py
+ en/
+ __init__.py
+ formats.py
+
+where :file:`formats.py` contains custom format definitions. For example::
+
+ THOUSAND_SEPARATOR = ' '
+
+to use a space as a thousand separator, instead of the default for English,
+a comma.
diff --git a/docs/topics/install.txt b/docs/topics/install.txt
index 0a64e3258d..d53f49de46 100644
--- a/docs/topics/install.txt
+++ b/docs/topics/install.txt
@@ -53,7 +53,7 @@ for each platform.
.. _Apache: http://httpd.apache.org/
.. _mod_wsgi: http://code.google.com/p/modwsgi/
-.. _WSGI: http://www.python.org/peps/pep-0333.html
+.. _WSGI: http://www.python.org/dev/peps/pep-0333/
.. _server-arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements
.. _database-installation:
@@ -125,7 +125,7 @@ Django will need permission to create a test database.
.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
.. _SQLite: http://www.sqlite.org/
-.. _pysqlite: http://pysqlite.org/
+.. _pysqlite: http://trac.edgewall.org/wiki/PySqlite
.. _cx_Oracle: http://cx-oracle.sourceforge.net/
.. _Oracle: http://www.oracle.com/
.. _Sybase SQL Anywhere: http://code.google.com/p/sqlany-django/
diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt
index 751ff27b79..62b8869313 100644
--- a/docs/topics/serialization.txt
+++ b/docs/topics/serialization.txt
@@ -154,10 +154,10 @@ to install third-party Python modules:
.. _PyYAML: http://www.pyyaml.org/
Notes for specific serialization formats
-----------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
json
-~~~~
+^^^^
If you're using UTF-8 (or any other non-ASCII encoding) data with the JSON
serializer, you must pass ``ensure_ascii=False`` as a parameter to the
@@ -191,3 +191,191 @@ them. Something like this will work::
.. _special encoder: http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.7/docs/index.html
+.. _topics-serialization-natural-keys:
+
+Natural keys
+------------
+
+The default serialization strategy for foreign keys and many-to-many
+relations is to serialize the value of the primary key(s) of the
+objects in the relation. This strategy works well for most types of
+object, but it can cause difficulty in some circumstances.
+
+Consider the case of a list of objects that have foreign key on
+:class:`ContentType`. If you're going to serialize an object that
+refers to a content type, you need to have a way to refer to that
+content type. Content Types are automatically created by Django as
+part of the database synchronization process, so you don't need to
+include content types in a fixture or other serialized data. As a
+result, the primary key of any given content type isn't easy to
+predict - it will depend on how and when :djadmin:`syncdb` was
+executed to create the content types.
+
+There is also the matter of convenience. An integer id isn't always
+the most convenient way to refer to an object; sometimes, a
+more natural reference would be helpful.
+
+Deserialization of natural keys
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is for these reasons that Django provides `natural keys`. A natural
+key is a tuple of values that can be used to uniquely identify an
+object instance without using the primary key value.
+
+Consider the following two models::
+
+ from django.db import models
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+ class Book(models.Model):
+ name = models.CharField(max_length=100)
+ author = models.ForeignKey(Person)
+
+Ordinarily, serialized data for ``Book`` would use an integer to refer to
+the author. For example, in JSON, a Book might be serialized as::
+
+ ...
+ {
+ "pk": 1,
+ "model": "store.book",
+ "fields": {
+ "name": "Mostly Harmless",
+ "author": 42
+ }
+ }
+ ...
+
+This isn't a particularly natural way to refer to an author. It
+requires that you know the primary key value for the author; it also
+requires that this primary key value is stable and predictable.
+
+However, if we add natural key handling to Person, the fixture becomes
+much more humane. To add natural key handling, you define a default
+Manager for Person with a ``get_by_natural_key()`` method. In the case
+of a Person, a good natural key might be the pair of first and last
+name::
+
+ from django.db import models
+
+ class PersonManager(models.Manager):
+ def get_by_natural_key(self, first_name, last_name):
+ return self.get(first_name=first_name, last_name=last_name)
+
+ class Person(models.Model):
+ objects = PersonManager()
+
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+Now books can use that natural key to refer to ``Person`` objects::
+
+ ...
+ {
+ "pk": 1,
+ "model": "store.book",
+ "fields": {
+ "name": "Mostly Harmless",
+ "author": ["Douglas", "Adams"]
+ }
+ }
+ ...
+
+When you try to load this serialized data, Django will use the
+``get_by_natural_key()`` method to resolve ``["Douglas", "Adams"]``
+into the primary key of an actual ``Person`` object.
+
+Serialization of natural keys
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+So how do you get Django to emit a natural key when serializing an object?
+Firstly, you need to add another method -- this time to the model itself::
+
+ class Person(models.Model):
+ objects = PersonManager()
+
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+ def natural_key(self):
+ return (self.first_name, self.last_name)
+
+Then, when you call ``serializers.serialize()``, you provide a
+``use_natural_keys=True`` argument::
+
+ >>> serializers.serialize([book1, book2], format='json', indent=2, use_natural_keys=True)
+
+When ``use_natural_keys=True`` is specified, Django will use the
+``natural_key()`` method to serialize any reference to objects of the
+type that defines the method.
+
+If you are using :djadmin:`dumpdata` to generate serialized data, you
+use the `--natural` command line flag to generate natural keys.
+
+.. note::
+
+ You don't need to define both ``natural_key()`` and
+ ``get_by_natural_key()``. If you don't want Django to output
+ natural keys during serialization, but you want to retain the
+ ability to load natural keys, then you can opt to not implement
+ the ``natural_key()`` method.
+
+ Conversely, if (for some strange reason) you want Django to output
+ natural keys during serialization, but *not* be able to load those
+ key values, just don't define the ``get_by_natural_key()`` method.
+
+Dependencies during serialization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since natural keys rely on database lookups to resolve references, it
+is important that data exists before it is referenced. You can't make
+a `forward reference` with natural keys - the data you are referencing
+must exist before you include a natural key reference to that data.
+
+To accommodate this limitation, calls to :djadmin:`dumpdata` that use
+the :djadminopt:`--natural` optionwill serialize any model with a
+``natural_key()`` method before it serializes normal key objects.
+
+However, this may not always be enough. If your natural key refers to
+another object (by using a foreign key or natural key to another object
+as part of a natural key), then you need to be able to ensure that
+the objects on which a natural key depends occur in the serialized data
+before the natural key requires them.
+
+To control this ordering, you can define dependencies on your
+``natural_key()`` methods. You do this by setting a ``dependencies``
+attribute on the ``natural_key()`` method itself.
+
+For example, consider the ``Permission`` model in ``contrib.auth``.
+The following is a simplified version of the ``Permission`` model::
+
+ class Permission(models.Model):
+ name = models.CharField(max_length=50)
+ content_type = models.ForeignKey(ContentType)
+ codename = models.CharField(max_length=100)
+ # ...
+ def natural_key(self):
+ return (self.codename,) + self.content_type.natural_key()
+
+The natural key for a ``Permission`` is a combination of the codename for the
+``Permission``, and the ``ContentType`` to which the ``Permission`` applies. This means
+that ``ContentType`` must be serialized before ``Permission``. To define this
+dependency, we add one extra line::
+
+ class Permission(models.Model):
+ # ...
+ def natural_key(self):
+ return (self.codename,) + self.content_type.natural_key()
+ natural_key.dependencies = ['contenttypes.contenttype']
+
+This definition ensures that ``ContentType`` models are serialized before
+``Permission`` models. In turn, any object referencing ``Permission`` will
+be serialized after both ``ContentType`` and ``Permission``.
diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt
index 1c8b63c61e..41cb94a56d 100644
--- a/docs/topics/templates.txt
+++ b/docs/topics/templates.txt
@@ -187,8 +187,8 @@ tags:
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
-
- :ttag:`if` and :ttag:`else`
+
+ :ttag:`if` and ``else``
Evaluates a variable, and if that variable is "true" the contents of the
block are displayed::
@@ -200,20 +200,15 @@ tags:
In the above, if ``athlete_list`` is not empty, the number of athletes
will be displayed by the ``{{ athlete_list|length }}`` variable.
-
- :ttag:`ifequal` and :ttag:`ifnotequal`
- Display some contents if two arguments are or are not equal. For example::
- {% ifequal athlete.name coach.name %}
- ...
- {% endifequal %}
+ You can also use filters and various operators in the ``if`` tag::
- Or::
+ {% if athlete_list|length > 1 %}
+ Team: {% for athlete in athlete_list %} ... {% endfor %}
+ {% else %}
+ Athlete: {{ athlete_list.0.name }}
+ {% endif %}
- {% ifnotequal athlete.name "Joe" %}
- ...
- {% endifnotequal %}
-
:ttag:`block` and :ttag:`extends`
Set up `template inheritance`_ (see below), a powerful way
of cutting down on "boilerplate" in templates.
diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt
index a9ba66ece0..9ef6cceae8 100644
--- a/docs/topics/testing.txt
+++ b/docs/topics/testing.txt
@@ -147,7 +147,7 @@ as must have ``CREATE DATABASE`` rights.
For more details about how doctest works, see the `standard library
documentation for doctest`_.
-.. _doctest: http://docs.python.org/lib/module-doctest.html
+.. _doctest: http://docs.python.org/library/doctest.html
.. _standard library documentation for doctest: doctest_
Writing unit tests
@@ -197,9 +197,9 @@ suite.
For more details about ``unittest``, see the `standard library unittest
documentation`_.
-.. _unittest: http://docs.python.org/lib/module-unittest.html
+.. _unittest: http://docs.python.org/library/unittest.html
.. _standard library unittest documentation: unittest_
-.. _suggested organization: http://docs.python.org/lib/organizing-tests.html
+.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
Which should I use?
-------------------
@@ -278,33 +278,35 @@ The test database
-----------------
Tests that require a database (namely, model tests) will not use your "real"
-(production) database. A separate, blank database is created for the tests.
+(production) database. Separate, blank databases are created for the tests.
-Regardless of whether the tests pass or fail, the test database is destroyed
+Regardless of whether the tests pass or fail, the test databases are destroyed
when all the tests have been executed.
-By default this test database gets its name by prepending ``test_`` to the
-value of the :setting:`DATABASE_NAME` setting. When using the SQLite database
-engine the tests will by default use an in-memory database (i.e., the database
-will be created in memory, bypassing the filesystem entirely!). If you want to
-use a different database name, specify the :setting:`TEST_DATABASE_NAME`
-setting.
+By default the test databases get their names by prepending ``test_``
+to the value of the :setting:`NAME`` settings for the databased
+defined in :setting:`DATABASES`. When using the SQLite database engine
+the tests will by default use an in-memory database (i.e., the
+database will be created in memory, bypassing the filesystem
+entirely!). If you want to use a different database name, specify
+``TEST_NAME`` in the dictionary for any given database in
+:setting:`DATABASES`.
-Aside from using a separate database, the test runner will otherwise use all of
-the same database settings you have in your settings file:
-:setting:`DATABASE_ENGINE`, :setting:`DATABASE_USER`, :setting:`DATABASE_HOST`,
-etc. The test database is created by the user specified by
-:setting:`DATABASE_USER`, so you'll need to make sure that the given user
-account has sufficient privileges to create a new database on the system.
+Aside from using a separate database, the test runner will otherwise
+use all of the same database settings you have in your settings file:
+:setting:`ENGINE`, :setting:`USER`, :setting:`HOST`, etc. The test
+database is created by the user specified by ``USER``, so you'll need
+to make sure that the given user account has sufficient privileges to
+create a new database on the system.
.. versionadded:: 1.0
-For fine-grained control over the
-character encoding of your test database, use the
-:setting:`TEST_DATABASE_CHARSET` setting. If you're using MySQL, you can also
-use the :setting:`TEST_DATABASE_COLLATION` setting to control the particular
-collation used by the test database. See the :ref:`settings documentation
-<ref-settings>` for details of these advanced settings.
+For fine-grained control over the character encoding of your test
+database, use the :setting:`TEST_CHARSET` option. If you're using
+MySQL, you can also use the :setting:`TEST_COLLATION` option to
+control the particular collation used by the test database. See the
+:ref:`settings documentation <ref-settings>` for details of these
+advanced settings.
Other test conditions
---------------------
@@ -412,7 +414,7 @@ a different focus. In short:
A comprehensive test suite should use a combination of both test types.
.. _Twill: http://twill.idyll.org/
-.. _Selenium: http://www.openqa.org/selenium/
+.. _Selenium: http://seleniumhq.org/
Overview and a quick example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -465,8 +467,8 @@ Note a few important things about how the test client works:
This black magic (essentially a patching of Django's template system in
memory) only happens during test running.
-.. _urllib: http://docs.python.org/lib/module-urllib.html
-.. _urllib2: http://docs.python.org/lib/module-urllib2.html
+.. _urllib: http://docs.python.org/library/urllib.html
+.. _urllib2: http://docs.python.org/library/urllib2.html
Making requests
~~~~~~~~~~~~~~~
@@ -807,7 +809,7 @@ can access these properties as part of a test condition.
A dictionary-like object containing session information. See the
:ref:`session documentation<topics-http-sessions>` for full details.
-.. _Cookie module documentation: http://docs.python.org/lib/module-Cookie.html
+.. _Cookie module documentation: http://docs.python.org/library/cookie.html
Example
~~~~~~~
@@ -1037,6 +1039,39 @@ URLconf for the duration of the test case.
.. _emptying-test-outbox:
+Multi-database support
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. attribute:: TestCase.multi_db
+
+.. versionadded:: 1.2
+
+Django sets up a test database corresponding to every database that is
+defined in the :setting:``DATABASES`` definition in your settings
+file. However, a big part of the time taken to run a Django TestCase
+is consumed by the call to ``flush`` that ensures that you have a
+clean database at the start of each test run. If you have multiple
+databases, multiple flushes are required (one for each database),
+which can be a time consuming activity -- especially if your tests
+don't need to test multi-database activity.
+
+As an optimization, Django only flushes the ``default`` database at
+the start of each test run. If your setup contains multiple databases,
+and you have a test that requires every database to be clean, you can
+use the ``multi_db`` attribute on the test suite to request a full
+flush.
+
+For example::
+
+ class TestMyViews(TestCase):
+ multi_db = True
+
+ def testIndexPageView(self):
+ call_some_test_code()
+
+This test case will flush *all* the test databases before running
+``testIndexPageView``.
+
Emptying the test outbox
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1251,16 +1286,17 @@ utility methods in the ``django.test.utils`` module.
.. function:: setup_test_environment()
Performs any global pre-test setup, such as the installing the
- instrumentation of the template rendering system and setting up the dummy
- ``SMTPConnection``.
+ instrumentation of the template rendering system and setting up
+ the dummy ``SMTPConnection``.
.. function:: teardown_test_environment()
- Performs any global post-test teardown, such as removing the black magic
- hooks into the template system and restoring normal e-mail services.
+ Performs any global post-test teardown, such as removing the black
+ magic hooks into the template system and restoring normal e-mail
+ services.
-The creation module of the database backend (``connection.creation``) also
-provides some utilities that can be useful during testing.
+The creation module of the database backend (``connection.creation``)
+also provides some utilities that can be useful during testing.
.. function:: create_test_db(verbosity=1, autoclobber=False)
@@ -1268,27 +1304,29 @@ provides some utilities that can be useful during testing.
``verbosity`` has the same behavior as in ``run_tests()``.
- ``autoclobber`` describes the behavior that will occur if a database with
- the same name as the test database is discovered:
+ ``autoclobber`` describes the behavior that will occur if a
+ database with the same name as the test database is discovered:
- * If ``autoclobber`` is ``False``, the user will be asked to approve
- destroying the existing database. ``sys.exit`` is called if the user
- does not approve.
+ * If ``autoclobber`` is ``False``, the user will be asked to
+ approve destroying the existing database. ``sys.exit`` is
+ called if the user does not approve.
- * If autoclobber is ``True``, the database will be destroyed without
- consulting the user.
+ * If autoclobber is ``True``, the database will be destroyed
+ without consulting the user.
Returns the name of the test database that it created.
- ``create_test_db()`` has the side effect of modifying
- ``settings.DATABASE_NAME`` to match the name of the test database.
+ ``create_test_db()`` has the side effect of modifying the value of
+ :setting:`NAME` in :setting:`DATABASES` to match the name of the test
+ database.
.. versionchanged:: 1.0
``create_test_db()`` now returns the name of the test database.
.. function:: destroy_test_db(old_database_name, verbosity=1)
- Destroys the database whose name is in the :setting:`DATABASE_NAME` setting
- and restores the value of :setting:`DATABASE_NAME` to the provided name.
+ Destroys the database whose name is in stored in :setting:`NAME` in the
+ :setting:`DATABASES`, and sets :setting:`NAME` to use the
+ provided name.
``verbosity`` has the same behavior as in ``run_tests()``.