Fixed many more ReST indentation errors, somehow accidentally missed from [16955]

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16983 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant 2011-10-14 00:12:01 +00:00
parent 5109ac3709
commit d1e5c55258
129 changed files with 5708 additions and 5740 deletions

View File

@ -8,16 +8,16 @@ The login cookie isn't being set correctly, because the domain of the cookie
sent out by Django doesn't match the domain in your browser. Try these two sent out by Django doesn't match the domain in your browser. Try these two
things: things:
* Set the :setting:`SESSION_COOKIE_DOMAIN` setting in your admin config * Set the :setting:`SESSION_COOKIE_DOMAIN` setting in your admin config
file to match your domain. For example, if you're going to file to match your domain. For example, if you're going to
"http://www.example.com/admin/" in your browser, in "http://www.example.com/admin/" in your browser, in
"myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``. "myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``.
* Some browsers (Firefox?) don't like to accept cookies from domains that * Some browsers (Firefox?) don't like to accept cookies from domains that
don't have dots in them. If you're running the admin site on "localhost" don't have dots in them. If you're running the admin site on "localhost"
or another domain that doesn't have a dot in it, try going to or another domain that doesn't have a dot in it, try going to
"localhost.localdomain" or "127.0.0.1". And set "localhost.localdomain" or "127.0.0.1". And set
:setting:`SESSION_COOKIE_DOMAIN` accordingly. :setting:`SESSION_COOKIE_DOMAIN` accordingly.
I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error. I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.
----------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -26,17 +26,17 @@ The best way to make sure tickets do not get hung up on the way to checkin is
to make it dead easy, even for someone who may not be intimately familiar with to make it dead easy, even for someone who may not be intimately familiar with
that area of the code, to understand the problem and verify the fix: that area of the code, to understand the problem and verify the fix:
* Are there clear instructions on how to reproduce the bug? If this * Are there clear instructions on how to reproduce the bug? If this
touches a dependency (such as PIL), a contrib module, or a specific touches a dependency (such as PIL), a contrib module, or a specific
database, are those instructions clear enough even for someone not database, are those instructions clear enough even for someone not
familiar with it? familiar with it?
* If there are several patches attached to the ticket, is it clear what * If there are several patches attached to the ticket, is it clear what
each one does, which ones can be ignored and which matter? each one does, which ones can be ignored and which matter?
* Does the patch include a unit test? If not, is there a very clear * Does the patch include a unit test? If not, is there a very clear
explanation why not? A test expresses succinctly what the problem is, explanation why not? A test expresses succinctly what the problem is,
and shows that the patch actually fixes it. and shows that the patch actually fixes it.
If your patch stands no chance of inclusion in Django, we won't ignore it -- If your patch stands no chance of inclusion in Django, we won't ignore it --
we'll just close the ticket. So if your ticket is still open, it doesn't mean we'll just close the ticket. So if your ticket is still open, it doesn't mean

View File

@ -4,11 +4,11 @@ FAQ: Installation
How do I get started? How do I get started?
--------------------- ---------------------
#. `Download the code`_. #. `Download the code`_.
#. Install Django (read the :doc:`installation guide </intro/install>`). #. Install Django (read the :doc:`installation guide </intro/install>`).
#. Walk through the :doc:`tutorial </intro/tutorial01>`. #. Walk through the :doc:`tutorial </intro/tutorial01>`.
#. Check out the rest of the :doc:`documentation </index>`, and `ask questions`_ if you #. Check out the rest of the :doc:`documentation </index>`, and `ask questions`_ if you
run into trouble. run into trouble.
.. _`Download the code`: http://www.djangoproject.com/download/ .. _`Download the code`: http://www.djangoproject.com/download/
.. _ask questions: http://www.djangoproject.com/community/ .. _ask questions: http://www.djangoproject.com/community/

View File

@ -6,21 +6,21 @@ Why do I get an error about importing DJANGO_SETTINGS_MODULE?
Make sure that: Make sure that:
* The environment variable DJANGO_SETTINGS_MODULE is set to a * The environment variable DJANGO_SETTINGS_MODULE is set to a
fully-qualified Python module (i.e. "mysite.settings"). fully-qualified Python module (i.e. "mysite.settings").
* Said module is on ``sys.path`` (``import mysite.settings`` should work). * Said module is on ``sys.path`` (``import mysite.settings`` should work).
* The module doesn't contain syntax errors (of course). * The module doesn't contain syntax errors (of course).
* If you're using mod_python but *not* using Django's request handler, * If you're using mod_python but *not* using Django's request handler,
you'll need to work around a mod_python bug related to the use of you'll need to work around a mod_python bug related to the use of
``SetEnv``; before you import anything from Django you'll need to do ``SetEnv``; before you import anything from Django you'll need to do
the following:: the following::
os.environ.update(req.subprocess_env) os.environ.update(req.subprocess_env)
(where ``req`` is the mod_python request object). (where ``req`` is the mod_python request object).
I can't stand your template language. Do I have to use it? I can't stand your template language. Do I have to use it?
---------------------------------------------------------- ----------------------------------------------------------
@ -46,25 +46,25 @@ How do I use image and file fields?
Using a :class:`~django.db.models.FileField` or an Using a :class:`~django.db.models.FileField` or an
:class:`~django.db.models.ImageField` in a model takes a few steps: :class:`~django.db.models.ImageField` in a model takes a few steps:
#. In your settings file, you'll need to define :setting:`MEDIA_ROOT` as #. In your settings file, you'll need to define :setting:`MEDIA_ROOT` as
the full path to a directory where you'd like Django to store uploaded the full path to a directory where you'd like Django to store uploaded
files. (For performance, these files are not stored in the database.) files. (For performance, these files are not stored in the database.)
Define :setting:`MEDIA_URL` as the base public URL of that directory. Define :setting:`MEDIA_URL` as the base public URL of that directory.
Make sure that this directory is writable by the Web server's user Make sure that this directory is writable by the Web server's user
account. account.
#. Add the :class:`~django.db.models.FileField` or #. Add the :class:`~django.db.models.FileField` or
:class:`~django.db.models.ImageField` to your model, making sure to :class:`~django.db.models.ImageField` to your model, making sure to
define the :attr:`~django.db.models.FileField.upload_to` option to tell define the :attr:`~django.db.models.FileField.upload_to` option to tell
Django to which subdirectory of :setting:`MEDIA_ROOT` it should upload Django to which subdirectory of :setting:`MEDIA_ROOT` it should upload
files. files.
#. All that will be stored in your database is a path to the file #. All that will be stored in your database is a path to the file
(relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the (relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the
convenience :attr:`~django.core.files.File.url` attribute provided by convenience :attr:`~django.core.files.File.url` attribute provided by
Django. For example, if your :class:`~django.db.models.ImageField` is Django. For example, if your :class:`~django.db.models.ImageField` is
called ``mug_shot``, you can get the absolute path to your image in a called ``mug_shot``, you can get the absolute path to your image in a
template with ``{{ object.mug_shot.url }}``. template with ``{{ object.mug_shot.url }}``.
How do I make a variable available to all my templates? How do I make a variable available to all my templates?
------------------------------------------------------- -------------------------------------------------------

View File

@ -14,12 +14,12 @@ dealing with Apache, you can configuring Apache to authenticate against Django's
:doc:`authentication system </topics/auth>` directly. For example, you :doc:`authentication system </topics/auth>` directly. For example, you
could: could:
* Serve static/media files directly from Apache only to authenticated users. * Serve static/media files directly from Apache only to authenticated users.
* Authenticate access to a Subversion_ repository against Django users with * Authenticate access to a Subversion_ repository against Django users with
a certain permission. a certain permission.
* Allow certain users to connect to a WebDAV share created with mod_dav_. * Allow certain users to connect to a WebDAV share created with mod_dav_.
.. _Subversion: http://subversion.tigris.org/ .. _Subversion: http://subversion.tigris.org/
.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html .. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
@ -93,29 +93,29 @@ By default, the authentication handler will limit access to the ``/example/``
location to users marked as staff members. You can use a set of location to users marked as staff members. You can use a set of
``PythonOption`` directives to modify this behavior: ``PythonOption`` directives to modify this behavior:
================================ ========================================= ================================ =========================================
``PythonOption`` Explanation ``PythonOption`` Explanation
================================ ========================================= ================================ =========================================
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e. ``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
those with the ``is_staff`` flag set) those with the ``is_staff`` flag set)
will be allowed. will be allowed.
Defaults to ``on``. Defaults to ``on``.
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e. ``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
those with the ``is_superuser`` flag set) those with the ``is_superuser`` flag set)
will be allowed. will be allowed.
Defaults to ``off``. Defaults to ``off``.
``DjangoPermissionName`` The name of a permission to require for ``DjangoPermissionName`` The name of a permission to require for
access. See :ref:`custom permissions access. See :ref:`custom permissions
<custom-permissions>` for more <custom-permissions>` for more
information. information.
By default no specific permission will be By default no specific permission will be
required. required.
================================ ========================================= ================================ =========================================
Note that sometimes ``SetEnv`` doesn't play well in this mod_python Note that sometimes ``SetEnv`` doesn't play well in this mod_python
configuration, for reasons unknown. If you're having problems getting configuration, for reasons unknown. If you're having problems getting

View File

@ -37,11 +37,11 @@ You'll need to follow these steps:
Your custom storage system may override any of the storage methods explained in Your custom storage system may override any of the storage methods explained in
:doc:`/ref/files/storage`, but you **must** implement the following methods: :doc:`/ref/files/storage`, but you **must** implement the following methods:
* :meth:`Storage.delete` * :meth:`Storage.delete`
* :meth:`Storage.exists` * :meth:`Storage.exists`
* :meth:`Storage.listdir` * :meth:`Storage.listdir`
* :meth:`Storage.size` * :meth:`Storage.size`
* :meth:`Storage.url` * :meth:`Storage.url`
You'll also usually want to use hooks specifically designed for custom storage You'll also usually want to use hooks specifically designed for custom storage
objects. These are: objects. These are:

View File

@ -133,14 +133,14 @@ example). If this sounds a bit tricky, don't worry -- it will become clearer in
the examples below. Just remember that you will often end up creating two the examples below. Just remember that you will often end up creating two
classes when you want a custom field: classes when you want a custom field:
* The first class is the Python object that your users will manipulate. * The first class is the Python object that your users will manipulate.
They will assign it to the model attribute, they will read from it for They will assign it to the model attribute, they will read from it for
displaying purposes, things like that. This is the ``Hand`` class in our displaying purposes, things like that. This is the ``Hand`` class in our
example. example.
* The second class is the ``Field`` subclass. This is the class that knows * The second class is the ``Field`` subclass. This is the class that knows
how to convert your first class back and forth between its permanent how to convert your first class back and forth between its permanent
storage form and the Python form. storage form and the Python form.
Writing a field subclass Writing a field subclass
======================== ========================
@ -198,33 +198,33 @@ card values plus their suits; 104 characters in total.
The :meth:`~django.db.models.Field.__init__` method takes the following The :meth:`~django.db.models.Field.__init__` method takes the following
parameters: parameters:
* :attr:`~django.db.models.Field.verbose_name` * :attr:`~django.db.models.Field.verbose_name`
* :attr:`~django.db.models.Field.name` * :attr:`~django.db.models.Field.name`
* :attr:`~django.db.models.Field.primary_key` * :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.Field.max_length` * :attr:`~django.db.models.Field.max_length`
* :attr:`~django.db.models.Field.unique` * :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank` * :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null` * :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index` * :attr:`~django.db.models.Field.db_index`
* :attr:`~django.db.models.Field.rel`: Used for related fields (like * :attr:`~django.db.models.Field.rel`: Used for related fields (like
:class:`ForeignKey`). For advanced use only. :class:`ForeignKey`). For advanced use only.
* :attr:`~django.db.models.Field.default` * :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable` * :attr:`~django.db.models.Field.editable`
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will * :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
not be serialized when the model is passed to Django's :doc:`serializers not be serialized when the model is passed to Django's :doc:`serializers
</topics/serialization>`. Defaults to ``True``. </topics/serialization>`. Defaults to ``True``.
* :attr:`~django.db.models.Field.unique_for_date` * :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month` * :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year` * :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices` * :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text` * :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column` * :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with * :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
the Oracle backend and only for index creation. You can usually ignore the Oracle backend and only for index creation. You can usually ignore
this option. this option.
* :attr:`~django.db.models.Field.auto_created`: True if the field was * :attr:`~django.db.models.Field.auto_created`: True if the field was
automatically created, as for the `OneToOneField` used by model automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only. inheritance. For advanced use only.
All of the options without an explanation in the above list have the same All of the options without an explanation in the above list have the same
meaning they do for normal Django fields. See the :doc:`field documentation meaning they do for normal Django fields. See the :doc:`field documentation
@ -415,11 +415,11 @@ that are more complex than strings, dates, integers or floats, then you'll need
to override this method. As a general rule, the method should deal gracefully to override this method. As a general rule, the method should deal gracefully
with any of the following arguments: with any of the following arguments:
* An instance of the correct type (e.g., ``Hand`` in our ongoing example). * An instance of the correct type (e.g., ``Hand`` in our ongoing example).
* A string (e.g., from a deserializer). * A string (e.g., from a deserializer).
* Whatever the database returns for the column type you're using. * Whatever the database returns for the column type you're using.
In our ``HandField`` class, we're storing the data as a VARCHAR field in the In our ``HandField`` class, we're storing the data as a VARCHAR field in the
database, so we need to be able to process strings and ``Hand`` instances in database, so we need to be able to process strings and ``Hand`` instances in
@ -695,19 +695,19 @@ complex conversions between your Python types and your database and
serialization formats. Here are a couple of tips to make things go more serialization formats. Here are a couple of tips to make things go more
smoothly: smoothly:
1. Look at the existing Django fields (in 1. Look at the existing Django fields (in
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find :file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
a field that's similar to what you want and extend it a little bit, a field that's similar to what you want and extend it a little bit,
instead of creating an entirely new field from scratch. instead of creating an entirely new field from scratch.
2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're 2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
wrapping up as a field. There are a lot of places where the default wrapping up as a field. There are a lot of places where the default
behavior of the field code is to call behavior of the field code is to call
:func:`~django.utils.encoding.force_unicode` on the value. (In our :func:`~django.utils.encoding.force_unicode` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your :meth:`__unicode__` method automatically ``HandField``). So if your :meth:`__unicode__` method automatically
converts to the string form of your Python object, you can save yourself converts to the string form of your Python object, you can save yourself
a lot of work. a lot of work.
Writing a ``FileField`` subclass Writing a ``FileField`` subclass
@ -735,14 +735,14 @@ A few suggestions
In addition to the above details, there are a few guidelines which can greatly In addition to the above details, there are a few guidelines which can greatly
improve the efficiency and readability of the field's code. improve the efficiency and readability of the field's code.
1. The source for Django's own ``ImageField`` (in 1. The source for Django's own ``ImageField`` (in
``django/db/models/fields/files.py``) is a great example of how to ``django/db/models/fields/files.py``) is a great example of how to
subclass ``FileField`` to support a particular type of file, as it subclass ``FileField`` to support a particular type of file, as it
incorporates all of the techniques described above. incorporates all of the techniques described above.
2. Cache file attributes wherever possible. Since files may be stored in 2. Cache file attributes wherever possible. Since files may be stored in
remote storage systems, retrieving them may cost extra time, or even remote storage systems, retrieving them may cost extra time, or even
money, that isn't always necessary. Once a file is retrieved to obtain money, that isn't always necessary. Once a file is retrieved to obtain
some data about its content, cache as much of that data as possible to some data about its content, cache as much of that data as possible to
reduce the number of times the file must be retrieved on subsequent reduce the number of times the file must be retrieved on subsequent
calls for that information. calls for that information.

View File

@ -77,9 +77,9 @@ Writing custom template filters
Custom filters are just Python functions that take one or two arguments: Custom filters are just Python functions that take one or two arguments:
* The value of the variable (input) -- not necessarily a string. * The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left * The value of the argument -- this can have a default value, or be left
out altogether. out altogether.
For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
passed the variable ``var`` and the argument ``"bar"``. passed the variable ``var`` and the argument ``"bar"``.
@ -124,9 +124,9 @@ your ``Library`` instance, to make it available to Django's template language:
The ``Library.filter()`` method takes two arguments: The ``Library.filter()`` method takes two arguments:
1. The name of the filter -- a string. 1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the 2. The compilation function -- a Python function (not the name of the
function as a string). function as a string).
You can use ``register.filter()`` as a decorator instead: You can use ``register.filter()`` as a decorator instead:
@ -173,156 +173,156 @@ When writing a custom filter, give some thought to how the filter will interact
with Django's auto-escaping behavior. Note that three types of strings can be with Django's auto-escaping behavior. Note that three types of strings can be
passed around inside the template code: passed around inside the template code:
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On * **Raw strings** are the native Python ``str`` or ``unicode`` types. On
output, they're escaped if auto-escaping is in effect and presented output, they're escaped if auto-escaping is in effect and presented
unchanged, otherwise. unchanged, otherwise.
* **Safe strings** are strings that have been marked safe from further * **Safe strings** are strings that have been marked safe from further
escaping at output time. Any necessary escaping has already been done. escaping at output time. Any necessary escaping has already been done.
They're commonly used for output that contains raw HTML that is intended They're commonly used for output that contains raw HTML that is intended
to be interpreted as-is on the client side. to be interpreted as-is on the client side.
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``. Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
They share a common base class of ``SafeData``, so you can test They share a common base class of ``SafeData``, so you can test
for them using code like: for them using code like:
.. code-block:: python .. code-block:: python
if isinstance(value, SafeData): if isinstance(value, SafeData):
# Do something with the "safe" string. # Do something with the "safe" string.
... ...
* **Strings marked as "needing escaping"** are *always* escaped on * **Strings marked as "needing escaping"** are *always* escaped on
output, regardless of whether they are in an :ttag:`autoescape` block or output, regardless of whether they are in an :ttag:`autoescape` block or
not. These strings are only escaped once, however, even if auto-escaping not. These strings are only escaped once, however, even if auto-escaping
applies. applies.
Internally, these strings are of type ``EscapeString`` or Internally, these strings are of type ``EscapeString`` or
``EscapeUnicode``. Generally you don't have to worry about these; they ``EscapeUnicode``. Generally you don't have to worry about these; they
exist for the implementation of the :tfilter:`escape` filter. exist for the implementation of the :tfilter:`escape` filter.
Template filter code falls into one of two situations: Template filter code falls into one of two situations:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``, 1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In ``'``, ``"`` or ``&``) into the result that were not already present. In
this case, you can let Django take care of all the auto-escaping this case, you can let Django take care of all the auto-escaping
handling for you. All you need to do is put the ``is_safe`` attribute on handling for you. All you need to do is put the ``is_safe`` attribute on
your filter function and set it to ``True``, like so: your filter function and set it to ``True``, like so:
.. code-block:: python .. code-block:: python
@register.filter @register.filter
def myfilter(value): def myfilter(value):
return value return value
myfilter.is_safe = True myfilter.is_safe = True
This attribute tells Django that if a "safe" string is passed into your This attribute tells Django that if a "safe" string is passed into your
filter, the result will still be "safe" and if a non-safe string is filter, the result will still be "safe" and if a non-safe string is
passed in, Django will automatically escape it, if necessary. passed in, Django will automatically escape it, if necessary.
You can think of this as meaning "this filter is safe -- it doesn't You can think of this as meaning "this filter is safe -- it doesn't
introduce any possibility of unsafe HTML." introduce any possibility of unsafe HTML."
The reason ``is_safe`` is necessary is because there are plenty of The reason ``is_safe`` is necessary is because there are plenty of
normal string operations that will turn a ``SafeData`` object back into normal string operations that will turn a ``SafeData`` object back into
a normal ``str`` or ``unicode`` object and, rather than try to catch a normal ``str`` or ``unicode`` object and, rather than try to catch
them all, which would be very difficult, Django repairs the damage after them all, which would be very difficult, Django repairs the damage after
the filter has completed. the filter has completed.
For example, suppose you have a filter that adds the string ``xx`` to For example, suppose you have a filter that adds the string ``xx`` to
the end of any input. Since this introduces no dangerous HTML characters the end of any input. Since this introduces no dangerous HTML characters
to the result (aside from any that were already present), you should to the result (aside from any that were already present), you should
mark your filter with ``is_safe``: mark your filter with ``is_safe``:
.. code-block:: python .. code-block:: python
@register.filter @register.filter
def add_xx(value): def add_xx(value):
return '%sxx' % value return '%sxx' % value
add_xx.is_safe = True add_xx.is_safe = True
When this filter is used in a template where auto-escaping is enabled, When this filter is used in a template where auto-escaping is enabled,
Django will escape the output whenever the input is not already marked Django will escape the output whenever the input is not already marked
as "safe". as "safe".
By default, ``is_safe`` defaults to ``False``, and you can omit it from By default, ``is_safe`` defaults to ``False``, and you can omit it from
any filters where it isn't required. any filters where it isn't required.
Be careful when deciding if your filter really does leave safe strings Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave as safe. If you're *removing* characters, you might inadvertently leave
unbalanced HTML tags or entities in the result. For example, removing a unbalanced HTML tags or entities in the result. For example, removing a
``>`` from the input might turn ``<a>`` into ``<a``, which would need to ``>`` from the input might turn ``<a>`` into ``<a``, which would need to
be escaped on output to avoid causing problems. Similarly, removing a be escaped on output to avoid causing problems. Similarly, removing a
semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
valid entity and thus needs further escaping. Most cases won't be nearly valid entity and thus needs further escaping. Most cases won't be nearly
this tricky, but keep an eye out for any problems like that when this tricky, but keep an eye out for any problems like that when
reviewing your code. reviewing your code.
Marking a filter ``is_safe`` will coerce the filter's return value to Marking a filter ``is_safe`` will coerce the filter's return value to
a string. If your filter should return a boolean or other non-string a string. If your filter should return a boolean or other non-string
value, marking it ``is_safe`` will probably have unintended value, marking it ``is_safe`` will probably have unintended
consequences (such as converting a boolean False to the string consequences (such as converting a boolean False to the string
'False'). 'False').
2. Alternatively, your filter code can manually take care of any necessary 2. Alternatively, your filter code can manually take care of any necessary
escaping. This is necessary when you're introducing new HTML markup into escaping. This is necessary when you're introducing new HTML markup into
the result. You want to mark the output as safe from further the result. You want to mark the output as safe from further
escaping so that your HTML markup isn't escaped further, so you'll need escaping so that your HTML markup isn't escaped further, so you'll need
to handle the input yourself. to handle the input yourself.
To mark the output as a safe string, use To mark the output as a safe string, use
:func:`django.utils.safestring.mark_safe`. :func:`django.utils.safestring.mark_safe`.
Be careful, though. You need to do more than just mark the output as Be careful, though. You need to do more than just mark the output as
safe. You need to ensure it really *is* safe, and what you do depends on safe. You need to ensure it really *is* safe, and what you do depends on
whether auto-escaping is in effect. The idea is to write filters than whether auto-escaping is in effect. The idea is to write filters than
can operate in templates where auto-escaping is either on or off in can operate in templates where auto-escaping is either on or off in
order to make things easier for your template authors. order to make things easier for your template authors.
In order for your filter to know the current auto-escaping state, set In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` if keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise. auto-escaping is in effect and ``False`` otherwise.
For example, let's write a filter that emphasizes the first character of For example, let's write a filter that emphasizes the first character of
a string: a string:
.. code-block:: python .. code-block:: python
from django.utils.html import conditional_escape from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
def initial_letter_filter(text, autoescape=None): def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:] first, other = text[0], text[1:]
if autoescape: if autoescape:
esc = conditional_escape esc = conditional_escape
else: else:
esc = lambda x: x esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other)) result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result) return mark_safe(result)
initial_letter_filter.needs_autoescape = True initial_letter_filter.needs_autoescape = True
The ``needs_autoescape`` attribute on the filter function and the The ``needs_autoescape`` attribute on the filter function and the
``autoescape`` keyword argument mean that our function will know whether ``autoescape`` keyword argument mean that our function will know whether
automatic escaping is in effect when the filter is called. We use automatic escaping is in effect when the filter is called. We use
``autoescape`` to decide whether the input data needs to be passed ``autoescape`` to decide whether the input data needs to be passed
through ``django.utils.html.conditional_escape`` or not. (In the latter through ``django.utils.html.conditional_escape`` or not. (In the latter
case, we just use the identity function as the "escape" function.) The case, we just use the identity function as the "escape" function.) The
``conditional_escape()`` function is like ``escape()`` except it only ``conditional_escape()`` function is like ``escape()`` except it only
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData`` escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
instance is passed to ``conditional_escape()``, the data is returned instance is passed to ``conditional_escape()``, the data is returned
unchanged. unchanged.
Finally, in the above example, we remember to mark the result as safe Finally, in the above example, we remember to mark the result as safe
so that our HTML is inserted directly into the template without further so that our HTML is inserted directly into the template without further
escaping. escaping.
There's no need to worry about the ``is_safe`` attribute in this case There's no need to worry about the ``is_safe`` attribute in this case
(although including it wouldn't hurt anything). Whenever you manually (although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the handle the auto-escaping issues and return a safe string, the
``is_safe`` attribute won't change anything either way. ``is_safe`` attribute won't change anything either way.
Writing custom template tags Writing custom template tags
---------------------------- ----------------------------
@ -381,37 +381,37 @@ object:
Notes: Notes:
* ``parser`` is the template parser object. We don't need it in this * ``parser`` is the template parser object. We don't need it in this
example. example.
* ``token.contents`` is a string of the raw contents of the tag. In our * ``token.contents`` is a string of the raw contents of the tag. In our
example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``. example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
* The ``token.split_contents()`` method separates the arguments on spaces * The ``token.split_contents()`` method separates the arguments on spaces
while keeping quoted strings together. The more straightforward while keeping quoted strings together. The more straightforward
``token.contents.split()`` wouldn't be as robust, as it would naively ``token.contents.split()`` wouldn't be as robust, as it would naively
split on *all* spaces, including those within quoted strings. It's a good split on *all* spaces, including those within quoted strings. It's a good
idea to always use ``token.split_contents()``. idea to always use ``token.split_contents()``.
* This function is responsible for raising * This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for ``django.template.TemplateSyntaxError``, with helpful messages, for
any syntax error. any syntax error.
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable. * The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
Don't hard-code the tag's name in your error messages, because that Don't hard-code the tag's name in your error messages, because that
couples the tag's name to your function. ``token.contents.split()[0]`` couples the tag's name to your function. ``token.contents.split()[0]``
will ''always'' be the name of your tag -- even when the tag has no will ''always'' be the name of your tag -- even when the tag has no
arguments. arguments.
* The function returns a ``CurrentTimeNode`` with everything the node needs * The function returns a ``CurrentTimeNode`` with everything the node needs
to know about this tag. In this case, it just passes the argument -- to know about this tag. In this case, it just passes the argument --
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
template tag are removed in ``format_string[1:-1]``. template tag are removed in ``format_string[1:-1]``.
* The parsing is very low-level. The Django developers have experimented * The parsing is very low-level. The Django developers have experimented
with writing small frameworks on top of this parsing system, using with writing small frameworks on top of this parsing system, using
techniques such as EBNF grammars, but those experiments made the template techniques such as EBNF grammars, but those experiments made the template
engine too slow. It's low-level because that's fastest. engine too slow. It's low-level because that's fastest.
Writing the renderer Writing the renderer
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
@ -433,14 +433,14 @@ Continuing the above example, we need to define ``CurrentTimeNode``:
Notes: Notes:
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``. * ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
Always pass any options/parameters/arguments to a ``Node`` via its Always pass any options/parameters/arguments to a ``Node`` via its
``__init__()``. ``__init__()``.
* The ``render()`` method is where the work actually happens. * The ``render()`` method is where the work actually happens.
* ``render()`` should never raise ``TemplateSyntaxError`` or any other * ``render()`` should never raise ``TemplateSyntaxError`` or any other
exception. It should fail silently, just as template filters should. exception. It should fail silently, just as template filters should.
Ultimately, this decoupling of compilation and rendering results in an Ultimately, this decoupling of compilation and rendering results in an
efficient template system, because a template can render multiple contexts efficient template system, because a template can render multiple contexts
@ -525,14 +525,14 @@ A naive implementation of ``CycleNode`` might look something like this:
But, suppose we have two templates rendering the template snippet from above at But, suppose we have two templates rendering the template snippet from above at
the same time: the same time:
1. Thread 1 performs its first loop iteration, ``CycleNode.render()`` 1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
returns 'row1' returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()`` 2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
returns 'row2' returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()`` 3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
returns 'row1' returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()`` 4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
returns 'row2' returns 'row2'
The CycleNode is iterating, but it's iterating globally. As far as Thread 1 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 and Thread 2 are concerned, it's always returning the same value. This is
@ -584,10 +584,10 @@ in "Writing custom template filters" above. Example:
The ``tag()`` method takes two arguments: The ``tag()`` method takes two arguments:
1. The name of the template tag -- a string. If this is left out, the 1. The name of the template tag -- a string. If this is left out, the
name of the compilation function will be used. name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the 2. The compilation function -- a Python function (not the name of the
function as a string). function as a string).
As with filter registration, it is also possible to use this as a decorator: As with filter registration, it is also possible to use this as a decorator:
@ -623,12 +623,12 @@ tag format that date-time:
Initially, ``token.split_contents()`` will return three values: Initially, ``token.split_contents()`` will return three values:
1. The tag name ``format_time``. 1. The tag name ``format_time``.
2. The string ``"blog_entry.date_updated"`` (without the surrounding 2. The string ``"blog_entry.date_updated"`` (without the surrounding
quotes). quotes).
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from 3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
``split_contents()`` will include the leading and trailing quotes for ``split_contents()`` will include the leading and trailing quotes for
string literals like this. string literals like this.
Now your tag should begin to look like this: Now your tag should begin to look like this:
@ -706,12 +706,12 @@ The decorator syntax also works:
A few things to note about the ``simple_tag`` helper function: A few things to note about the ``simple_tag`` helper function:
* Checking for the required number of arguments, etc., has already been * Checking for the required number of arguments, etc., has already been
done by the time our function is called, so we don't need to do that. done by the time our function is called, so we don't need to do that.
* The quotes around the argument (if any) have already been stripped away, * The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string. so we just receive a plain string.
* If the argument was a template variable, our function is passed the * If the argument was a template variable, our function is passed the
current value of the variable, not the variable itself. current value of the variable, not the variable itself.
.. versionadded:: 1.3 .. versionadded:: 1.3

View File

@ -168,9 +168,9 @@ Once you've got that set up, point Apache at your Django FastCGI instance by
editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two
things: things:
* Use the ``FastCGIExternalServer`` directive to specify the location of * Use the ``FastCGIExternalServer`` directive to specify the location of
your FastCGI server. your FastCGI server.
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate. * Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html .. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

View File

@ -240,11 +240,11 @@ server you choose.
We recommend using a separate Web server -- i.e., one that's not also running We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices: Django -- for serving media. Here are some good choices:
* lighttpd_ * lighttpd_
* Nginx_ * Nginx_
* TUX_ * TUX_
* A stripped-down version of Apache_ * A stripped-down version of Apache_
* Cherokee_ * Cherokee_
If, however, you have no option but to serve media or static files on the If, however, you have no option but to serve media or static files on the
same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python
@ -299,11 +299,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches: the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your 1. Create a symbolic link to the admin static files from within your
document root. document root.
2. Or, copy the admin static files so that they live within your Apache 2. Or, copy the admin static files so that they live within your Apache
document root. document root.
Using "eggs" with mod_python Using "eggs" with mod_python
============================ ============================
@ -362,15 +362,15 @@ If you get a segmentation fault
If Apache causes a segmentation fault, there are two probable causes, neither If Apache causes a segmentation fault, there are two probable causes, neither
of which has to do with Django itself. of which has to do with Django itself.
1. It may be because your Python code is importing the "pyexpat" module, 1. It may be because your Python code is importing the "pyexpat" module,
which may conflict with the version embedded in Apache. For full which may conflict with the version embedded in Apache. For full
information, see `Expat Causing Apache Crash`_. information, see `Expat Causing Apache Crash`_.
2. It may be because you're running mod_python and mod_php in the same 2. It may be because you're running mod_python and mod_php in the same
Apache instance, with MySQL as your database backend. In some cases, Apache instance, with MySQL as your database backend. In some cases,
this causes a known mod_python issue due to version conflicts in PHP and this causes a known mod_python issue due to version conflicts in PHP and
the Python MySQL backend. There's full information in the the Python MySQL backend. There's full information in the
`mod_python FAQ entry`_. `mod_python FAQ entry`_.
If you continue to have problems setting up mod_python, a good thing to do is If you continue to have problems setting up mod_python, a good thing to do is
get a barebones mod_python site working, without the Django framework. This is get a barebones mod_python site working, without the Django framework. This is

View File

@ -64,11 +64,11 @@ server you choose.
We recommend using a separate Web server -- i.e., one that's not also running We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices: Django -- for serving media. Here are some good choices:
* lighttpd_ * lighttpd_
* Nginx_ * Nginx_
* TUX_ * TUX_
* A stripped-down version of Apache_ * A stripped-down version of Apache_
* Cherokee_ * Cherokee_
If, however, you have no option but to serve media files on the same Apache If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, you can set up Apache to serve some URLs as ``VirtualHost`` as Django, you can set up Apache to serve some URLs as
@ -131,11 +131,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches: the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your 1. Create a symbolic link to the admin static files from within your
document root. document root.
2. Or, copy the admin static files so that they live within your Apache 2. Or, copy the admin static files so that they live within your Apache
document root. document root.
Details Details
======= =======

View File

@ -56,12 +56,12 @@ setting.
Django can also be configured to email errors about broken links (404 "page Django can also be configured to email errors about broken links (404 "page
not found" errors). Django sends emails about 404 errors when: not found" errors). Django sends emails about 404 errors when:
* :setting:`DEBUG` is ``False`` * :setting:`DEBUG` is ``False``
* :setting:`SEND_BROKEN_LINK_EMAILS` is ``True`` * :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware`` * Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
(which it does by default). (which it does by default).
If those conditions are met, Django will email the users listed in the If those conditions are met, Django will email the users listed in the
:setting:`MANAGERS` setting whenever your code raises a 404 and the request has :setting:`MANAGERS` setting whenever your code raises a 404 and the request has
@ -144,18 +144,16 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
If a function (either a view or any regular callback) in your code uses If a function (either a view or any regular callback) in your code uses
local variables susceptible to contain sensitive information, you may local variables susceptible to contain sensitive information, you may
prevent the values of those variables from being included in error reports prevent the values of those variables from being included in error reports
using the ``sensitive_variables`` decorator: using the ``sensitive_variables`` decorator::
.. code-block:: python from django.views.decorators.debug import sensitive_variables
from django.views.decorators.debug import sensitive_variables @sensitive_variables('user', 'pw', 'cc')
def process_info(user):
@sensitive_variables('user', 'pw', 'cc') pw = user.pass_word
def process_info(user): cc = user.credit_card_number
pw = user.pass_word name = user.name
cc = user.credit_card_number ...
name = user.name
...
In the above example, the values for the ``user``, ``pw`` and ``cc`` In the above example, the values for the ``user``, ``pw`` and ``cc``
variables will be hidden and replaced with stars (`**********`) in the variables will be hidden and replaced with stars (`**********`) in the
@ -163,13 +161,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
disclosed. disclosed.
To systematically hide all local variables of a function from error logs, To systematically hide all local variables of a function from error logs,
do not provide any argument to the ``sensitive_variables`` decorator: do not provide any argument to the ``sensitive_variables`` decorator::
.. code-block:: python @sensitive_variables()
def my_function():
@sensitive_variables() ...
def my_function():
...
.. function:: sensitive_post_parameters(*parameters) .. function:: sensitive_post_parameters(*parameters)
@ -177,19 +173,17 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
:attr:`POST parameters<HttpRequest.POST>` susceptible to contain sensitive :attr:`POST parameters<HttpRequest.POST>` susceptible to contain sensitive
information, you may prevent the values of those parameters from being information, you may prevent the values of those parameters from being
included in the error reports using the ``sensitive_post_parameters`` included in the error reports using the ``sensitive_post_parameters``
decorator: decorator::
.. code-block:: python from django.views.decorators.debug import sensitive_post_parameters
from django.views.decorators.debug import sensitive_post_parameters @sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
@sensitive_post_parameters('pass_word', 'credit_card_number') UserProfile.create(user=request.user,
def record_user_profile(request): password=request.POST['pass_word'],
UserProfile.create(user=request.user, credit_card=request.POST['credit_card_number'],
password=request.POST['pass_word'], name=request.POST['name'])
credit_card=request.POST['credit_card_number'], ...
name=request.POST['name'])
...
In the above example, the values for the ``pass_word`` and In the above example, the values for the ``pass_word`` and
``credit_card_number`` POST parameters will be hidden and replaced with ``credit_card_number`` POST parameters will be hidden and replaced with
@ -197,13 +191,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
reports, whereas the value of the ``name`` parameter will be disclosed. reports, whereas the value of the ``name`` parameter will be disclosed.
To systematically hide all POST parameters of a request in error reports, To systematically hide all POST parameters of a request in error reports,
do not provide any argument to the ``sensitive_post_parameters`` decorator: do not provide any argument to the ``sensitive_post_parameters`` decorator::
.. code-block:: python @sensitive_post_parameters()
def my_view(request):
@sensitive_post_parameters() ...
def my_view(request):
...
.. note:: .. note::
@ -231,22 +223,18 @@ decorators' annotations to replace the corresponding values with stars
(`**********`) when the error reports are produced. If you wish to override or (`**********`) when the error reports are produced. If you wish to override or
customize this default behavior for your entire site, you need to define your customize this default behavior for your entire site, you need to define your
own filter class and tell Django to use it via the own filter class and tell Django to use it via the
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting: :setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting::
.. code-block:: python DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
You may also control in a more granular way which filter to use within any You may also control in a more granular way which filter to use within any
given view by setting the ``HttpRequest``'s ``exception_reporter_filter`` given view by setting the ``HttpRequest``'s ``exception_reporter_filter``
attribute: attribute::
.. code-block:: python def my_view(request):
if request.user.is_authenticated():
def my_view(request): request.exception_reporter_filter = CustomExceptionReporterFilter()
if request.user.is_authenticated(): ...
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
Your custom filter class needs to inherit from Your custom filter class needs to inherit from
:class:`django.views.debug.SafeExceptionReporterFilter` and may override the :class:`django.views.debug.SafeExceptionReporterFilter` and may override the

View File

@ -10,16 +10,16 @@ the order in which it examines the different file paths to load the compiled
:term:`message files <message file>` (``.mo``) and the precedence of multiple :term:`message files <message file>` (``.mo``) and the precedence of multiple
translations for the same literal: translations for the same literal:
1. The directories listed in :setting:`LOCALE_PATHS` have the highest 1. The directories listed in :setting:`LOCALE_PATHS` have the highest
precedence, with the ones appearing first having higher precedence than precedence, with the ones appearing first having higher precedence than
the ones appearing later. the ones appearing later.
2. Then, it looks for and uses if it exists a ``locale`` directory in each 2. Then, it looks for and uses if it exists a ``locale`` directory in each
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
appearing first have higher precedence than the ones appearing later. appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or 3. Then, it looks for a ``locale`` directory in the project directory, or
more accurately, in the directory containing your settings file. more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale`` 4. Finally, the Django-provided base translation in ``django/conf/locale``
is used as a fallback. is used as a fallback.
.. deprecated:: 1.3 .. deprecated:: 1.3
Lookup in the ``locale`` subdirectory of the directory containing your Lookup in the ``locale`` subdirectory of the directory containing your
@ -55,12 +55,12 @@ message file specific to the project you are composing. The choice is yours.
All message file repositories are structured the same way. They are: All message file repositories are structured the same way. They are:
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are * All paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)`` searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` -- * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above. deprecated, see above.
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)`` * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>` To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
tool. You only need to be in the same directory where the ``locale/`` directory tool. You only need to be in the same directory where the ``locale/`` directory

View File

@ -64,10 +64,10 @@ Differences with Django on Jython
At this point, Django on Jython should behave nearly identically to Django At this point, Django on Jython should behave nearly identically to Django
running on standard Python. However, are a few differences to keep in mind: running on standard Python. However, are a few differences to keep in mind:
* Remember to use the ``jython`` command instead of ``python``. The * Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistency, but if you're using Jython documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it you'll want to mentally replace ``python`` with ``jython`` every time it
occurs. occurs.
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable * Similarly, you'll need to use the ``JYTHONPATH`` environment variable
instead of ``PYTHONPATH``. instead of ``PYTHONPATH``.

View File

@ -20,12 +20,12 @@ 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'`` setting and assigning values to the following keys for the ``'default'``
connection: connection:
* :setting:`NAME` * :setting:`NAME`
* :setting:`ENGINE` * :setting:`ENGINE`
* :setting:`USER` * :setting:`USER`
* :setting:`PASSWORD` * :setting:`PASSWORD`
* :setting:`HOST` * :setting:`HOST`
* :setting:`PORT` * :setting:`PORT`
Auto-generate the models Auto-generate the models
======================== ========================

View File

@ -32,27 +32,27 @@ Here's an example::
The code and comments should be self-explanatory, but a few things deserve a The code and comments should be self-explanatory, but a few things deserve a
mention: mention:
* The response gets a special MIME type, :mimetype:`text/csv`. This tells * The response gets a special MIME type, :mimetype:`text/csv`. This tells
browsers that the document is a CSV file, rather than an HTML file. If browsers that the document is a CSV file, rather than an HTML file. If
you leave this off, browsers will probably interpret the output as HTML, you leave this off, browsers will probably interpret the output as HTML,
which will result in ugly, scary gobbledygook in the browser window. which will result in ugly, scary gobbledygook in the browser window.
* The response gets an additional ``Content-Disposition`` header, which * The response gets an additional ``Content-Disposition`` header, which
contains the name of the CSV file. This filename is arbitrary; call it contains the name of the CSV file. This filename is arbitrary; call it
whatever you want. It'll be used by browsers in the "Save as..." whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc. dialogue, etc.
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the * Hooking into the CSV-generation API is easy: Just pass ``response`` as the
first argument to ``csv.writer``. The ``csv.writer`` function expects a first argument to ``csv.writer``. The ``csv.writer`` function expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill. bill.
* For each row in your CSV file, call ``writer.writerow``, passing it an * For each row in your CSV file, call ``writer.writerow``, passing it an
iterable object such as a list or tuple. iterable object such as a list or tuple.
* The CSV module takes care of quoting for you, so you don't have to worry * The CSV module takes care of quoting for you, so you don't have to worry
about escaping strings with quotes or commas in them. Just pass about escaping strings with quotes or commas in them. Just pass
``writerow()`` your raw strings, and it'll do the right thing. ``writerow()`` your raw strings, and it'll do the right thing.
Handling Unicode Handling Unicode
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -62,13 +62,13 @@ Unicode internally this means strings read from sources such as
:class:`~django.http.HttpRequest` are potentially problematic. There are a few :class:`~django.http.HttpRequest` are potentially problematic. There are a few
options for handling this: options for handling this:
* Manually encode all Unicode objects to a compatible encoding. * Manually encode all Unicode objects to a compatible encoding.
* Use the ``UnicodeWriter`` class provided in the `csv module's examples * Use the ``UnicodeWriter`` class provided in the `csv module's examples
section`_. section`_.
* Use the `python-unicodecsv module`_, which aims to be a drop-in * Use the `python-unicodecsv module`_, which aims to be a drop-in
replacement for :mod:`csv` that gracefully handles Unicode. replacement for :mod:`csv` that gracefully handles Unicode.
For more information, see the Python documentation of the :mod:`csv` module. For more information, see the Python documentation of the :mod:`csv` module.

View File

@ -63,36 +63,36 @@ Here's a "Hello World" example::
The code and comments should be self-explanatory, but a few things deserve a The code and comments should be self-explanatory, but a few things deserve a
mention: mention:
* The response gets a special MIME type, :mimetype:`application/pdf`. This * The response gets a special MIME type, :mimetype:`application/pdf`. This
tells browsers that the document is a PDF file, rather than an HTML file. tells browsers that the document is a PDF file, rather than an HTML file.
If you leave this off, browsers will probably interpret the output as If you leave this off, browsers will probably interpret the output as
HTML, which would result in ugly, scary gobbledygook in the browser HTML, which would result in ugly, scary gobbledygook in the browser
window. window.
* The response gets an additional ``Content-Disposition`` header, which * The response gets an additional ``Content-Disposition`` header, which
contains the name of the PDF file. This filename is arbitrary: Call it contains the name of the PDF file. This filename is arbitrary: Call it
whatever you want. It'll be used by browsers in the "Save as..." whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc. dialogue, etc.
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this * The ``Content-Disposition`` header starts with ``'attachment; '`` in this
example. This forces Web browsers to pop-up a dialog box example. This forces Web browsers to pop-up a dialog box
prompting/confirming how to handle the document even if a default is set prompting/confirming how to handle the document even if a default is set
on the machine. If you leave off ``'attachment;'``, browsers will handle on the machine. If you leave off ``'attachment;'``, browsers will handle
the PDF using whatever program/plugin they've been configured to use for the PDF using whatever program/plugin they've been configured to use for
PDFs. Here's what that code would look like:: PDFs. Here's what that code would look like::
response['Content-Disposition'] = 'filename=somefilename.pdf' response['Content-Disposition'] = 'filename=somefilename.pdf'
* Hooking into the ReportLab API is easy: Just pass ``response`` as the * Hooking into the ReportLab API is easy: Just pass ``response`` as the
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill. bill.
* Note that all subsequent PDF-generation methods are called on the PDF * Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``. object (in this case, ``p``) -- not on ``response``.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF * Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file. file.
Complex PDFs Complex PDFs
============ ============
@ -137,13 +137,13 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`::
Further resources Further resources
================= =================
* PDFlib_ is another PDF-generation library that has Python bindings. To * PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article. use it with Django, just use the same concepts explained in this article.
* `Pisa XHTML2PDF`_ 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. an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It * 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 doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python. using ``system`` or ``popen`` and retrieve the output in Python.
.. _PDFlib: http://www.pdflib.org/ .. _PDFlib: http://www.pdflib.org/
.. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/ .. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/

View File

@ -345,11 +345,11 @@ Serving the app and your static files from the same server
If you want to serve your static files from the same server that's already If you want to serve your static files from the same server that's already
serving your site, the basic outline gets modified to look something like: serving your site, the basic outline gets modified to look something like:
* Push your code up to the deployment server. * Push your code up to the deployment server.
* On the server, run :djadmin:`collectstatic` to copy all the static files * On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`. into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's * Point your web server at :setting:`STATIC_ROOT`. For example, here's
:ref:`how to do this under Apache and mod_wsgi <serving-files>`. :ref:`how to do this under Apache and mod_wsgi <serving-files>`.
You'll probably want to automate this process, especially if you've got You'll probably want to automate this process, especially if you've got
multiple web servers. There's any number of ways to do this automation, but multiple web servers. There's any number of ways to do this automation, but
@ -386,11 +386,11 @@ Most larger Django apps use a separate Web server -- i.e., one that's not also
running Django -- for serving static files. This server often runs a different running Django -- for serving static files. This server often runs a different
type of web server -- faster but less full-featured. Some good choices are: type of web server -- faster but less full-featured. Some good choices are:
* lighttpd_ * lighttpd_
* Nginx_ * Nginx_
* TUX_ * TUX_
* Cherokee_ * Cherokee_
* A stripped-down version of Apache_ * A stripped-down version of Apache_
.. _lighttpd: http://www.lighttpd.net/ .. _lighttpd: http://www.lighttpd.net/
.. _Nginx: http://wiki.nginx.org/Main .. _Nginx: http://wiki.nginx.org/Main
@ -404,11 +404,11 @@ server's respective documentation for instructions.
Since your static file server won't be running Django, you'll need to modify Since your static file server won't be running Django, you'll need to modify
the deployment strategy to look something like: the deployment strategy to look something like:
* When your static files change, run :djadmin:`collectstatic` locally. * When your static files change, run :djadmin:`collectstatic` locally.
* Push your local :setting:`STATIC_ROOT` up to the static file server * Push your local :setting:`STATIC_ROOT` up to the static file server
into the directory that's being served. ``rsync`` is a good into the directory that's being served. ``rsync`` is a good
choice for this step since it only needs to transfer the choice for this step since it only needs to transfer the
bits of static files that have changed. bits of static files that have changed.
Here's how this might look in a fabfile:: Here's how this might look in a fabfile::
@ -479,27 +479,27 @@ Upgrading from ``django-staticfiles``
you're upgrading from `django-staticfiles`_ older than 1.0 (e.g. 0.3.4) to you're upgrading from `django-staticfiles`_ older than 1.0 (e.g. 0.3.4) to
``django.contrib.staticfiles``, you'll need to make a few changes: ``django.contrib.staticfiles``, you'll need to make a few changes:
* Application files should now live in a ``static`` directory in each app * Application files should now live in a ``static`` directory in each app
(`django-staticfiles`_ used the name ``media``, which was slightly (`django-staticfiles`_ used the name ``media``, which was slightly
confusing). confusing).
* The management commands ``build_static`` and ``resolve_static`` are now * The management commands ``build_static`` and ``resolve_static`` are now
called :djadmin:`collectstatic` and :djadmin:`findstatic`. called :djadmin:`collectstatic` and :djadmin:`findstatic`.
* The settings ``STATICFILES_PREPEND_LABEL_APPS``, * The settings ``STATICFILES_PREPEND_LABEL_APPS``,
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were ``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
removed. removed.
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the * The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
new :setting:`STATICFILES_FINDERS`. new :setting:`STATICFILES_FINDERS`.
* The default for :setting:`STATICFILES_STORAGE` was renamed from * The default for :setting:`STATICFILES_STORAGE` was renamed from
``staticfiles.storage.StaticFileStorage`` to ``staticfiles.storage.StaticFileStorage`` to
``staticfiles.storage.StaticFilesStorage`` ``staticfiles.storage.StaticFilesStorage``
* If using :ref:`runserver<staticfiles-runserver>` for local development * If using :ref:`runserver<staticfiles-runserver>` for local development
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add (and the :setting:`DEBUG` setting is ``True``), you no longer need to add
anything to your URLconf for serving static files in development. anything to your URLconf for serving static files in development.
Learn more Learn more
========== ==========

View File

@ -34,190 +34,190 @@ Having trouble? We'd like to help!
First steps First steps
=========== ===========
* **From scratch:** * **From scratch:**
:doc:`Overview <intro/overview>` | :doc:`Overview <intro/overview>` |
:doc:`Installation <intro/install>` :doc:`Installation <intro/install>`
* **Tutorial:** * **Tutorial:**
:doc:`Part 1 <intro/tutorial01>` | :doc:`Part 1 <intro/tutorial01>` |
:doc:`Part 2 <intro/tutorial02>` | :doc:`Part 2 <intro/tutorial02>` |
:doc:`Part 3 <intro/tutorial03>` | :doc:`Part 3 <intro/tutorial03>` |
:doc:`Part 4 <intro/tutorial04>` :doc:`Part 4 <intro/tutorial04>`
The model layer The model layer
=============== ===============
* **Models:** * **Models:**
:doc:`Model syntax <topics/db/models>` | :doc:`Model syntax <topics/db/models>` |
:doc:`Field types <ref/models/fields>` | :doc:`Field types <ref/models/fields>` |
:doc:`Meta options <ref/models/options>` :doc:`Meta options <ref/models/options>`
* **QuerySets:** * **QuerySets:**
:doc:`Executing queries <topics/db/queries>` | :doc:`Executing queries <topics/db/queries>` |
:doc:`QuerySet method reference <ref/models/querysets>` :doc:`QuerySet method reference <ref/models/querysets>`
* **Model instances:** * **Model instances:**
:doc:`Instance methods <ref/models/instances>` | :doc:`Instance methods <ref/models/instances>` |
:doc:`Accessing related objects <ref/models/relations>` :doc:`Accessing related objects <ref/models/relations>`
* **Advanced:** * **Advanced:**
:doc:`Managers <topics/db/managers>` | :doc:`Managers <topics/db/managers>` |
:doc:`Raw SQL <topics/db/sql>` | :doc:`Raw SQL <topics/db/sql>` |
:doc:`Transactions <topics/db/transactions>` | :doc:`Transactions <topics/db/transactions>` |
:doc:`Aggregation <topics/db/aggregation>` | :doc:`Aggregation <topics/db/aggregation>` |
:doc:`Custom fields <howto/custom-model-fields>` | :doc:`Custom fields <howto/custom-model-fields>` |
:doc:`Multiple databases <topics/db/multi-db>` :doc:`Multiple databases <topics/db/multi-db>`
* **Other:** * **Other:**
:doc:`Supported databases <ref/databases>` | :doc:`Supported databases <ref/databases>` |
:doc:`Legacy databases <howto/legacy-databases>` | :doc:`Legacy databases <howto/legacy-databases>` |
:doc:`Providing initial data <howto/initial-data>` | :doc:`Providing initial data <howto/initial-data>` |
:doc:`Optimize database access <topics/db/optimization>` :doc:`Optimize database access <topics/db/optimization>`
The template layer The template layer
================== ==================
* **For designers:** * **For designers:**
:doc:`Syntax overview <topics/templates>` | :doc:`Syntax overview <topics/templates>` |
:doc:`Built-in tags and filters <ref/templates/builtins>` :doc:`Built-in tags and filters <ref/templates/builtins>`
* **For programmers:** * **For programmers:**
:doc:`Template API <ref/templates/api>` | :doc:`Template API <ref/templates/api>` |
:doc:`Custom tags and filters <howto/custom-template-tags>` :doc:`Custom tags and filters <howto/custom-template-tags>`
The view layer The view layer
============== ==============
* **The basics:** * **The basics:**
:doc:`URLconfs <topics/http/urls>` | :doc:`URLconfs <topics/http/urls>` |
:doc:`View functions <topics/http/views>` | :doc:`View functions <topics/http/views>` |
:doc:`Shortcuts <topics/http/shortcuts>` | :doc:`Shortcuts <topics/http/shortcuts>` |
:doc:`Decorators <topics/http/decorators>` :doc:`Decorators <topics/http/decorators>`
* **Reference:** * **Reference:**
:doc:`Request/response objects <ref/request-response>` | :doc:`Request/response objects <ref/request-response>` |
:doc:`TemplateResponse objects <ref/template-response>` :doc:`TemplateResponse objects <ref/template-response>`
* **File uploads:** * **File uploads:**
:doc:`Overview <topics/http/file-uploads>` | :doc:`Overview <topics/http/file-uploads>` |
:doc:`File objects <ref/files/file>` | :doc:`File objects <ref/files/file>` |
:doc:`Storage API <ref/files/storage>` | :doc:`Storage API <ref/files/storage>` |
:doc:`Managing files <topics/files>` | :doc:`Managing files <topics/files>` |
:doc:`Custom storage <howto/custom-file-storage>` :doc:`Custom storage <howto/custom-file-storage>`
* **Generic views:** * **Generic views:**
:doc:`Overview<topics/class-based-views>` | :doc:`Overview<topics/class-based-views>` |
:doc:`Built-in generic views<ref/class-based-views>` :doc:`Built-in generic views<ref/class-based-views>`
* **Advanced:** * **Advanced:**
:doc:`Generating CSV <howto/outputting-csv>` | :doc:`Generating CSV <howto/outputting-csv>` |
:doc:`Generating PDF <howto/outputting-pdf>` :doc:`Generating PDF <howto/outputting-pdf>`
* **Middleware:** * **Middleware:**
:doc:`Overview <topics/http/middleware>` | :doc:`Overview <topics/http/middleware>` |
:doc:`Built-in middleware classes <ref/middleware>` :doc:`Built-in middleware classes <ref/middleware>`
Forms Forms
===== =====
* **The basics:** * **The basics:**
:doc:`Overview <topics/forms/index>` | :doc:`Overview <topics/forms/index>` |
:doc:`Form API <ref/forms/api>` | :doc:`Form API <ref/forms/api>` |
:doc:`Built-in fields <ref/forms/fields>` | :doc:`Built-in fields <ref/forms/fields>` |
:doc:`Built-in widgets <ref/forms/widgets>` :doc:`Built-in widgets <ref/forms/widgets>`
* **Advanced:** * **Advanced:**
:doc:`Forms for models <topics/forms/modelforms>` | :doc:`Forms for models <topics/forms/modelforms>` |
:doc:`Integrating media <topics/forms/media>` | :doc:`Integrating media <topics/forms/media>` |
:doc:`Formsets <topics/forms/formsets>` | :doc:`Formsets <topics/forms/formsets>` |
:doc:`Customizing validation <ref/forms/validation>` :doc:`Customizing validation <ref/forms/validation>`
* **Extras:** * **Extras:**
:doc:`Form preview <ref/contrib/formtools/form-preview>` | :doc:`Form preview <ref/contrib/formtools/form-preview>` |
:doc:`Form wizard <ref/contrib/formtools/form-wizard>` :doc:`Form wizard <ref/contrib/formtools/form-wizard>`
The development process The development process
======================= =======================
* **Settings:** * **Settings:**
:doc:`Overview <topics/settings>` | :doc:`Overview <topics/settings>` |
:doc:`Full list of settings <ref/settings>` :doc:`Full list of settings <ref/settings>`
* **Exceptions:** * **Exceptions:**
:doc:`Overview <ref/exceptions>` :doc:`Overview <ref/exceptions>`
* **django-admin.py and manage.py:** * **django-admin.py and manage.py:**
:doc:`Overview <ref/django-admin>` | :doc:`Overview <ref/django-admin>` |
:doc:`Adding custom commands <howto/custom-management-commands>` :doc:`Adding custom commands <howto/custom-management-commands>`
* **Testing:** :doc:`Overview <topics/testing>` * **Testing:** :doc:`Overview <topics/testing>`
* **Deployment:** * **Deployment:**
:doc:`Overview <howto/deployment/index>` | :doc:`Overview <howto/deployment/index>` |
:doc:`Apache/mod_wsgi <howto/deployment/modwsgi>` | :doc:`Apache/mod_wsgi <howto/deployment/modwsgi>` |
:doc:`uWSGI <howto/deployment/uwsgi>` | :doc:`uWSGI <howto/deployment/uwsgi>` |
:doc:`Apache/mod_python (deprecated) <howto/deployment/modpython>` | :doc:`Apache/mod_python (deprecated) <howto/deployment/modpython>` |
:doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` | :doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` |
:doc:`Apache authentication <howto/apache-auth>` | :doc:`Apache authentication <howto/apache-auth>` |
:doc:`Handling static files <howto/static-files>` | :doc:`Handling static files <howto/static-files>` |
:doc:`Tracking code errors by email <howto/error-reporting>` :doc:`Tracking code errors by email <howto/error-reporting>`
Other batteries included Other batteries included
======================== ========================
* :doc:`Admin site <ref/contrib/admin/index>` | :doc:`Admin actions <ref/contrib/admin/actions>` | :doc:`Admin documentation generator<ref/contrib/admin/admindocs>` * :doc:`Admin site <ref/contrib/admin/index>` | :doc:`Admin actions <ref/contrib/admin/actions>` | :doc:`Admin documentation generator<ref/contrib/admin/admindocs>`
* :doc:`Authentication <topics/auth>` * :doc:`Authentication <topics/auth>`
* :doc:`Cache system <topics/cache>` * :doc:`Cache system <topics/cache>`
* :doc:`Clickjacking protection <ref/clickjacking>` * :doc:`Clickjacking protection <ref/clickjacking>`
* :doc:`Comments <ref/contrib/comments/index>` | :doc:`Moderation <ref/contrib/comments/moderation>` | :doc:`Custom comments <ref/contrib/comments/custom>` * :doc:`Comments <ref/contrib/comments/index>` | :doc:`Moderation <ref/contrib/comments/moderation>` | :doc:`Custom comments <ref/contrib/comments/custom>`
* :doc:`Conditional content processing <topics/conditional-view-processing>` * :doc:`Conditional content processing <topics/conditional-view-processing>`
* :doc:`Content types <ref/contrib/contenttypes>` * :doc:`Content types <ref/contrib/contenttypes>`
* :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>` * :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>`
* :doc:`Cryptographic signing <topics/signing>` * :doc:`Cryptographic signing <topics/signing>`
* :doc:`Databrowse <ref/contrib/databrowse>` * :doc:`Databrowse <ref/contrib/databrowse>`
* :doc:`E-mail (sending) <topics/email>` * :doc:`E-mail (sending) <topics/email>`
* :doc:`Flatpages <ref/contrib/flatpages>` * :doc:`Flatpages <ref/contrib/flatpages>`
* :doc:`GeoDjango <ref/contrib/gis/index>` * :doc:`GeoDjango <ref/contrib/gis/index>`
* :doc:`Humanize <ref/contrib/humanize>` * :doc:`Humanize <ref/contrib/humanize>`
* :doc:`Internationalization <topics/i18n/index>` * :doc:`Internationalization <topics/i18n/index>`
* :doc:`Jython support <howto/jython>` * :doc:`Jython support <howto/jython>`
* :doc:`"Local flavor" <ref/contrib/localflavor>` * :doc:`"Local flavor" <ref/contrib/localflavor>`
* :doc:`Logging <topics/logging>` * :doc:`Logging <topics/logging>`
* :doc:`Messages <ref/contrib/messages>` * :doc:`Messages <ref/contrib/messages>`
* :doc:`Pagination <topics/pagination>` * :doc:`Pagination <topics/pagination>`
* :doc:`Redirects <ref/contrib/redirects>` * :doc:`Redirects <ref/contrib/redirects>`
* :doc:`Security <topics/security>` * :doc:`Security <topics/security>`
* :doc:`Serialization <topics/serialization>` * :doc:`Serialization <topics/serialization>`
* :doc:`Sessions <topics/http/sessions>` * :doc:`Sessions <topics/http/sessions>`
* :doc:`Signals <topics/signals>` * :doc:`Signals <topics/signals>`
* :doc:`Sitemaps <ref/contrib/sitemaps>` * :doc:`Sitemaps <ref/contrib/sitemaps>`
* :doc:`Sites <ref/contrib/sites>` * :doc:`Sites <ref/contrib/sites>`
* :doc:`Static Files <ref/contrib/staticfiles>` * :doc:`Static Files <ref/contrib/staticfiles>`
* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>` * :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
* :doc:`Unicode in Django <ref/unicode>` * :doc:`Unicode in Django <ref/unicode>`
* :doc:`Web design helpers <ref/contrib/webdesign>` * :doc:`Web design helpers <ref/contrib/webdesign>`
* :doc:`Validators <ref/validators>` * :doc:`Validators <ref/validators>`
* Function-based generic views (Deprecated) :doc:`Overview<topics/generic-views>` | :doc:`Built-in generic views<ref/generic-views>` | :doc:`Migration guide<topics/generic-views-migration>` * Function-based generic views (Deprecated) :doc:`Overview<topics/generic-views>` | :doc:`Built-in generic views<ref/generic-views>` | :doc:`Migration guide<topics/generic-views-migration>`
The Django open-source project The Django open-source project
============================== ==============================
* **Community:** * **Community:**
:doc:`How to get involved <internals/contributing/index>` | :doc:`How to get involved <internals/contributing/index>` |
:doc:`The release process <internals/release-process>` | :doc:`The release process <internals/release-process>` |
:doc:`Team of committers <internals/committers>` | :doc:`Team of committers <internals/committers>` |
:doc:`The Django source code repository <internals/svn>` :doc:`The Django source code repository <internals/svn>`
* **Design philosophies:** * **Design philosophies:**
:doc:`Overview <misc/design-philosophies>` :doc:`Overview <misc/design-philosophies>`
* **Documentation:** * **Documentation:**
:doc:`About this documentation <internals/contributing/writing-documentation>` :doc:`About this documentation <internals/contributing/writing-documentation>`
* **Third-party distributions:** * **Third-party distributions:**
:doc:`Overview <misc/distributions>` :doc:`Overview <misc/distributions>`
* **Django over time:** * **Django over time:**
:doc:`API stability <misc/api-stability>` | :doc:`API stability <misc/api-stability>` |
:doc:`Release notes and upgrading instructions <releases/index>` | :doc:`Release notes and upgrading instructions <releases/index>` |
:doc:`Deprecation Timeline <internals/deprecation>` :doc:`Deprecation Timeline <internals/deprecation>`

View File

@ -30,23 +30,23 @@ amount of overhead involved in working with any bug tracking system so your
help in keeping our ticket tracker as useful as possible is appreciated. In help in keeping our ticket tracker as useful as possible is appreciated. In
particular: particular:
* **Do** read the :doc:`FAQ </faq/index>` to see if your issue might * **Do** read the :doc:`FAQ </faq/index>` to see if your issue might
be a well-known question. be a well-known question.
* **Do** ask on `django-users`_ or `#django`_ *first* if you're not sure if * **Do** ask on `django-users`_ or `#django`_ *first* if you're not sure if
what you're seeing is a bug. what you're seeing is a bug.
* **Do** write complete, reproducible, specific bug reports. You must * **Do** write complete, reproducible, specific bug reports. You must
include a clear, concise description of the problem, and a set of include a clear, concise description of the problem, and a set of
instructions for replicating it. Add as much debug information as you can: instructions for replicating it. Add as much debug information as you can:
code snippets, test cases, exception backtraces, screenshots, etc. A nice code snippets, test cases, exception backtraces, screenshots, etc. A nice
small test case is the best way to report a bug, as it gives us an easy small test case is the best way to report a bug, as it gives us an easy
way to confirm the bug quickly. way to confirm the bug quickly.
* **Don't** post to `django-developers`_ just to announce that you have * **Don't** post to `django-developers`_ just to announce that you have
filed a bug report. All the tickets are mailed to another list, filed a bug report. All the tickets are mailed to another list,
`django-updates`_, which is tracked by developers and interested `django-updates`_, which is tracked by developers and interested
community members; we see them as they are filed. community members; we see them as they are filed.
To understand the lifecycle of your ticket once you have created it, refer to To understand the lifecycle of your ticket once you have created it, refer to
:doc:`triaging-tickets`. :doc:`triaging-tickets`.
@ -67,27 +67,27 @@ Reporting security issues
In the event of a confirmed vulnerability in Django itself, we will take the In the event of a confirmed vulnerability in Django itself, we will take the
following actions: following actions:
* Acknowledge to the reporter that we've received the report and that a * Acknowledge to the reporter that we've received the report and that a
fix is forthcoming. We'll give a rough timeline and ask the reporter fix is forthcoming. We'll give a rough timeline and ask the reporter
to keep the issue confidential until we announce it. to keep the issue confidential until we announce it.
* Focus on developing a fix as quickly as possible and produce patches * Focus on developing a fix as quickly as possible and produce patches
against the current and two previous releases. against the current and two previous releases.
* Determine a go-public date for announcing the vulnerability and the fix. * Determine a go-public date for announcing the vulnerability and the fix.
To try to mitigate a possible "arms race" between those applying the To try to mitigate a possible "arms race" between those applying the
patch and those trying to exploit the hole, we will not announce patch and those trying to exploit the hole, we will not announce
security problems immediately. security problems immediately.
* Pre-notify third-party distributors of Django ("vendors"). We will send * Pre-notify third-party distributors of Django ("vendors"). We will send
these vendor notifications through private email which will include these vendor notifications through private email which will include
documentation of the vulnerability, links to the relevant patch(es), and documentation of the vulnerability, links to the relevant patch(es), and
a request to keep the vulnerability confidential until the official a request to keep the vulnerability confidential until the official
go-public date. go-public date.
* Publicly announce the vulnerability and the fix on the pre-determined * Publicly announce the vulnerability and the fix on the pre-determined
go-public date. This will probably mean a new release of Django, but go-public date. This will probably mean a new release of Django, but
in some cases it may simply be patches against current releases. in some cases it may simply be patches against current releases.
Reporting user interface bugs and features Reporting user interface bugs and features
------------------------------------------ ------------------------------------------
@ -95,25 +95,25 @@ Reporting user interface bugs and features
If your bug or feature request touches on anything visual in nature, there If your bug or feature request touches on anything visual in nature, there
are a few additional guidelines to follow: are a few additional guidelines to follow:
* Include screenshots in your ticket which are the visual equivalent of a * Include screenshots in your ticket which are the visual equivalent of a
minimal testcase. Show off the issue, not the crazy customizations minimal testcase. Show off the issue, not the crazy customizations
you've made to your browser. you've made to your browser.
* If the issue is difficult to show off using a still image, consider
capturing a *brief* screencast. If your software permits it, capture only
the relevant area of the screen.
* If you're offering a patch which changes the look or behavior of Django's
UI, you **must** attach before *and* after screenshots/screencasts.
Tickets lacking these are difficult for triagers and core developers to
assess quickly.
* Screenshots don't absolve you of other good reporting practices. Make sure * If the issue is difficult to show off using a still image, consider
to include URLs, code snippets, and step-by-step instructions on how to capturing a *brief* screencast. If your software permits it, capture only
reproduce the behavior visible in the screenshots. the relevant area of the screen.
* Make sure to set the UI/UX flag on the ticket so interested parties can * If you're offering a patch which changes the look or behavior of Django's
find your ticket. UI, you **must** attach before *and* after screenshots/screencasts.
Tickets lacking these are difficult for triagers and core developers to
assess quickly.
* Screenshots don't absolve you of other good reporting practices. Make sure
to include URLs, code snippets, and step-by-step instructions on how to
reproduce the behavior visible in the screenshots.
* Make sure to set the UI/UX flag on the ticket so interested parties can
find your ticket.
Requesting features Requesting features
------------------- -------------------
@ -121,27 +121,27 @@ Requesting features
We're always trying to make Django better, and your feature requests are a key We're always trying to make Django better, and your feature requests are a key
part of that. Here are some tips on how to make a request most effectively: part of that. Here are some tips on how to make a request most effectively:
* Make sure the feature actually requires changes in Django's core. If your * Make sure the feature actually requires changes in Django's core. If your
idea can be developed as an independent application or module — for idea can be developed as an independent application or module — for
instance, you want to support another database engine — we'll probably instance, you want to support another database engine — we'll probably
suggest that you to develop it independently. Then, if your project suggest that you to develop it independently. Then, if your project
gathers sufficient community support, we may consider it for inclusion in gathers sufficient community support, we may consider it for inclusion in
Django. Django.
* First request the feature on the `django-developers`_ list, not in the * First request the feature on the `django-developers`_ list, not in the
ticket tracker. It'll get read more closely if it's on the mailing list. ticket tracker. It'll get read more closely if it's on the mailing list.
This is even more important for large-scale feature requests. We like to This is even more important for large-scale feature requests. We like to
discuss any big changes to Django's core on the mailing list before discuss any big changes to Django's core on the mailing list before
actually working on them. actually working on them.
* Describe clearly and concisely what the missing feature is and how you'd * Describe clearly and concisely what the missing feature is and how you'd
like to see it implemented. Include example code (non-functional is OK) like to see it implemented. Include example code (non-functional is OK)
if possible. if possible.
* Explain *why* you'd like the feature. In some cases this is obvious, but * Explain *why* you'd like the feature. In some cases this is obvious, but
since Django is designed to help real developers get real work done, since Django is designed to help real developers get real work done,
you'll need to explain it, if it isn't obvious why the feature would be you'll need to explain it, if it isn't obvious why the feature would be
useful. useful.
If core developers agree on the feature, then it's appropriate to create a If core developers agree on the feature, then it's appropriate to create a
ticket. Include a link the discussion on `django-developers`_ in the ticket ticket. Include a link the discussion on `django-developers`_ in the ticket
@ -165,14 +165,14 @@ have informal votes on `django-developers`_ about a feature. In these votes we
follow the voting style invented by Apache and used on Python itself, where follow the voting style invented by Apache and used on Python itself, where
votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean: votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean:
* +1: "I love the idea and I'm strongly committed to it." * +1: "I love the idea and I'm strongly committed to it."
* +0: "Sounds OK to me." * +0: "Sounds OK to me."
* -0: "I'm not thrilled, but I won't stand in the way." * -0: "I'm not thrilled, but I won't stand in the way."
* -1: "I strongly disagree and would be very unhappy to see the idea turn * -1: "I strongly disagree and would be very unhappy to see the idea turn
into reality." into reality."
Although these votes on `django-developers`_ are informal, they'll be taken very Although these votes on `django-developers`_ are informal, they'll be taken very
seriously. After a suitable voting period, if an obvious consensus arises we'll seriously. After a suitable voting period, if an obvious consensus arises we'll
@ -186,12 +186,12 @@ Any :doc:`core committer</internals/committers>` may call for a formal vote
using the same voting mechanism above. A proposition will be considered carried using the same voting mechanism above. A proposition will be considered carried
by the core team if: by the core team if:
* There are three "+1" votes from members of the core team. * There are three "+1" votes from members of the core team.
* There is no "-1" vote from any member of the core team. * There is no "-1" vote from any member of the core team.
* The :ref:`BDFLs<django-bdfls>` haven't stepped in and executed their * The :ref:`BDFLs<django-bdfls>` haven't stepped in and executed their
positive or negative veto. positive or negative veto.
When calling for a vote, the caller should specify a deadline by which When calling for a vote, the caller should specify a deadline by which
votes must be received. One week is generally suggested as the minimum votes must be received. One week is generally suggested as the minimum

View File

@ -38,58 +38,58 @@ Committing guidelines
Please follow these guidelines when committing code to Django's Subversion Please follow these guidelines when committing code to Django's Subversion
repository: repository:
* For any medium-to-big changes, where "medium-to-big" is according to * For any medium-to-big changes, where "medium-to-big" is according to
your judgment, please bring things up on the `django-developers`_ your judgment, please bring things up on the `django-developers`_
mailing list before making the change. mailing list before making the change.
If you bring something up on `django-developers`_ and nobody responds, If you bring something up on `django-developers`_ and nobody responds,
please don't take that to mean your idea is great and should be please don't take that to mean your idea is great and should be
implemented immediately because nobody contested it. Django's lead implemented immediately because nobody contested it. Django's lead
developers don't have a lot of time to read mailing-list discussions developers don't have a lot of time to read mailing-list discussions
immediately, so you may have to wait a couple of days before getting a immediately, so you may have to wait a couple of days before getting a
response. response.
* Write detailed commit messages in the past tense, not present tense. * Write detailed commit messages in the past tense, not present tense.
* Good: "Fixed Unicode bug in RSS API." * Good: "Fixed Unicode bug in RSS API."
* Bad: "Fixes Unicode bug in RSS API." * Bad: "Fixes Unicode bug in RSS API."
* Bad: "Fixing Unicode bug in RSS API." * Bad: "Fixing Unicode bug in RSS API."
* For commits to a branch, prefix the commit message with the branch name. * For commits to a branch, prefix the commit message with the branch name.
For example: "magic-removal: Added support for mind reading." For example: "magic-removal: Added support for mind reading."
* Limit commits to the most granular change that makes sense. This means, * Limit commits to the most granular change that makes sense. This means,
use frequent small commits rather than infrequent large commits. For use frequent small commits rather than infrequent large commits. For
example, if implementing feature X requires a small change to library Y, example, if implementing feature X requires a small change to library Y,
first commit the change to library Y, then commit feature X in a first commit the change to library Y, then commit feature X in a
separate commit. This goes a *long way* in helping all core Django separate commit. This goes a *long way* in helping all core Django
developers follow your changes. developers follow your changes.
* Separate bug fixes from feature changes. * Separate bug fixes from feature changes.
Bug fixes need to be added to the current bugfix branch as well as the Bug fixes need to be added to the current bugfix branch as well as the
current trunk. current trunk.
* If your commit closes a ticket in the Django `ticket tracker`_, begin * If your commit closes a ticket in the Django `ticket tracker`_, begin
your commit message with the text "Fixed #abc", where "abc" is the your commit message with the text "Fixed #abc", where "abc" is the
number of the ticket your commit fixes. Example: "Fixed #123 -- Added number of the ticket your commit fixes. Example: "Fixed #123 -- Added
support for foo". We've rigged Subversion and Trac so that any commit support for foo". We've rigged Subversion and Trac so that any commit
message in that format will automatically close the referenced ticket message in that format will automatically close the referenced ticket
and post a comment to it with the full commit message. and post a comment to it with the full commit message.
If your commit closes a ticket and is in a branch, use the branch name If your commit closes a ticket and is in a branch, use the branch name
first, then the "Fixed #abc." For example: first, then the "Fixed #abc." For example:
"magic-removal: Fixed #123 -- Added whizbang feature." "magic-removal: Fixed #123 -- Added whizbang feature."
For the curious: we're using a `Trac post-commit hook`_ for this. For the curious: we're using a `Trac post-commit hook`_ for this.
.. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook .. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook
* If your commit references a ticket in the Django `ticket tracker`_ but * If your commit references a ticket in the Django `ticket tracker`_ but
does *not* close the ticket, include the phrase "Refs #abc", where "abc" does *not* close the ticket, include the phrase "Refs #abc", where "abc"
is the number of the ticket your commit references. We've rigged is the number of the ticket your commit references. We've rigged
Subversion and Trac so that any commit message in that format will Subversion and Trac so that any commit message in that format will
automatically post a comment to the appropriate ticket. automatically post a comment to the appropriate ticket.
Reverting commits Reverting commits
----------------- -----------------
@ -97,35 +97,35 @@ Reverting commits
Nobody's perfect; mistakes will be committed. When a mistaken commit is Nobody's perfect; mistakes will be committed. When a mistaken commit is
discovered, please follow these guidelines: discovered, please follow these guidelines:
* Try very hard to ensure that mistakes don't happen. Just because we * Try very hard to ensure that mistakes don't happen. Just because we
have a reversion policy doesn't relax your responsibility to aim for have a reversion policy doesn't relax your responsibility to aim for
the highest quality possible. Really: double-check your work before the highest quality possible. Really: double-check your work before
you commit it in the first place! you commit it in the first place!
* If possible, have the original author revert his/her own commit. * If possible, have the original author revert his/her own commit.
* Don't revert another author's changes without permission from the * Don't revert another author's changes without permission from the
original author. original author.
* If the original author can't be reached (within a reasonable amount * If the original author can't be reached (within a reasonable amount
of time -- a day or so) and the problem is severe -- crashing bug, of time -- a day or so) and the problem is severe -- crashing bug,
major test failures, etc -- then ask for objections on the major test failures, etc -- then ask for objections on the
`django-developers`_ mailing list then revert if there are none. `django-developers`_ mailing list then revert if there are none.
* If the problem is small (a feature commit after feature freeze, * If the problem is small (a feature commit after feature freeze,
say), wait it out. say), wait it out.
* If there's a disagreement between the committer and the * If there's a disagreement between the committer and the
reverter-to-be then try to work it out on the `django-developers`_ reverter-to-be then try to work it out on the `django-developers`_
mailing list. If an agreement can't be reached then it should mailing list. If an agreement can't be reached then it should
be put to a vote. be put to a vote.
* If the commit introduced a confirmed, disclosed security * If the commit introduced a confirmed, disclosed security
vulnerability then the commit may be reverted immediately without vulnerability then the commit may be reverted immediately without
permission from anyone. permission from anyone.
* The release branch maintainer may back out commits to the release * The release branch maintainer may back out commits to the release
branch without permission if the commit breaks the release branch. branch without permission if the commit breaks the release branch.
.. _django-developers: http://groups.google.com/group/django-developers .. _django-developers: http://groups.google.com/group/django-developers
.. _ticket tracker: http://code.djangoproject.com/newticket .. _ticket tracker: http://code.djangoproject.com/newticket

View File

@ -6,43 +6,43 @@ Django is a community that lives on its volunteers. As it keeps growing, we
always need more people to help others. As soon as you learn Django, you can always need more people to help others. As soon as you learn Django, you can
contribute in many ways: contribute in many ways:
* Join the `django-users`_ mailing list and answer questions. This * Join the `django-users`_ mailing list and answer questions. This
mailing list has a huge audience, and we really want to maintain a mailing list has a huge audience, and we really want to maintain a
friendly and helpful atmosphere. If you're new to the Django community, friendly and helpful atmosphere. If you're new to the Django community,
you should read the `posting guidelines`_. you should read the `posting guidelines`_.
* Join the `#django IRC channel`_ on Freenode and answer questions. By * Join the `#django IRC channel`_ on Freenode and answer questions. By
explaining Django to other users, you're going to learn a lot about the explaining Django to other users, you're going to learn a lot about the
framework yourself. framework yourself.
* Blog about Django. We syndicate all the Django blogs we know about on * Blog about Django. We syndicate all the Django blogs we know about on
the `community page`_; if you'd like to see your blog on that page you the `community page`_; if you'd like to see your blog on that page you
can `register it here`_. can `register it here`_.
* Contribute to open-source Django projects, write some documentation, or * Contribute to open-source Django projects, write some documentation, or
release your own code as an open-source pluggable application. The release your own code as an open-source pluggable application. The
ecosystem of pluggable applications is a big strength of Django, help us ecosystem of pluggable applications is a big strength of Django, help us
build it! build it!
If you think working *with* Django is fun, wait until you start working *on* If you think working *with* Django is fun, wait until you start working *on*
it. We're passionate about helping Django users make the jump to contributing it. We're passionate about helping Django users make the jump to contributing
members of the community, so there are several ways you can help Django's members of the community, so there are several ways you can help Django's
development: development:
* :doc:`Report bugs <bugs-and-features>` in our `ticket tracker`_. * :doc:`Report bugs <bugs-and-features>` in our `ticket tracker`_.
* Join the `django-developers`_ mailing list and share your ideas for how * Join the `django-developers`_ mailing list and share your ideas for how
to improve Django. We're always open to suggestions. to improve Django. We're always open to suggestions.
* :doc:`Submit patches <writing-code/submitting-patches>` for new and/or * :doc:`Submit patches <writing-code/submitting-patches>` for new and/or
fixed behavior. If you're looking for an easy way to start contributing fixed behavior. If you're looking for an easy way to start contributing
to Django have a look at the `easy pickings`_ tickets. to Django have a look at the `easy pickings`_ tickets.
* :doc:`Improve the documentation <writing-documentation>` or * :doc:`Improve the documentation <writing-documentation>` or
:doc:`write unit tests <writing-code/unit-tests>`. :doc:`write unit tests <writing-code/unit-tests>`.
* :doc:`Triage tickets and review patches <triaging-tickets>` created by * :doc:`Triage tickets and review patches <triaging-tickets>` created by
other users. other users.
Really, **ANYONE** can do something to help make Django better and greater! Really, **ANYONE** can do something to help make Django better and greater!

View File

@ -19,31 +19,31 @@ go to the `translation team`_ page for that language. If you would like to help
out with translating or add a language that isn't yet translated, here's what to out with translating or add a language that isn't yet translated, here's what to
do: do:
* Join the `Django i18n mailing list`_ and introduce yourself. * Join the `Django i18n mailing list`_ and introduce yourself.
* Make sure you read the notes about :ref:`specialties-of-django-i18n`. * Make sure you read the notes about :ref:`specialties-of-django-i18n`.
* Signup at `Transifex`_ and visit the `Django project page`_. * Signup at `Transifex`_ and visit the `Django project page`_.
* On the `translation teams`_ page, choose the language team you want * On the `translation teams`_ page, choose the language team you want
to work with, **or** -- in case the language team doesn't exist yet -- to work with, **or** -- in case the language team doesn't exist yet --
request a new team by clicking on the "Request a new team" button request a new team by clicking on the "Request a new team" button
and select the appropriate language. and select the appropriate language.
* Then, click the "Join this Team" button to become a member of this team. * Then, click the "Join this Team" button to become a member of this team.
Every team has at least one coordinator who is responsible to review Every team has at least one coordinator who is responsible to review
your membership request. You can of course also contact the team your membership request. You can of course also contact the team
coordinator to clarify procedural problems and handle the actual coordinator to clarify procedural problems and handle the actual
translation process. translation process.
* Once you are a member of a team choose the translation resource you * Once you are a member of a team choose the translation resource you
want to update on the team page. For example the "core" resource refers want to update on the team page. For example the "core" resource refers
to the translation catalogue that contains all non-contrib translations. to the translation catalogue that contains all non-contrib translations.
Each of the contrib apps also have a resource (prefixed with "contrib"). Each of the contrib apps also have a resource (prefixed with "contrib").
.. note:: .. note::
For more information about how to use Transifex, read the For more information about how to use Transifex, read the
`Transifex User Guide`_. `Transifex User Guide`_.
Localization Localization
------------ ------------
@ -55,10 +55,10 @@ the date, time and numbers formatting particularities of your locale. See
The format files aren't managed by the use of Transifex. To change them, you The format files aren't managed by the use of Transifex. To change them, you
must :doc:`create a patch<writing-code/submitting-patches>` against the Django source tree, as for any code change: must :doc:`create a patch<writing-code/submitting-patches>` against the Django source tree, as for any code change:
* Create a diff against the current Subversion trunk. * Create a diff against the current Subversion trunk.
* Open a ticket in Django's ticket system, set its ``Component`` field to * Open a ticket in Django's ticket system, set its ``Component`` field to
``Translations``, and attach the patch to it. ``Translations``, and attach the patch to it.
.. _Transifex: http://www.transifex.net/ .. _Transifex: http://www.transifex.net/
.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/ .. _Django i18n mailing list: http://groups.google.com/group/django-i18n/

View File

@ -57,16 +57,16 @@ Since a picture is worth a thousand words, let's start there:
We've got two roles in this diagram: We've got two roles in this diagram:
* :doc:`Committers</internals/committers>` (also called core developers): * :doc:`Committers</internals/committers>` (also called core developers):
people with commit access who are responsible for making the big people with commit access who are responsible for making the big
decisions, writing large portions of the code and integrating the decisions, writing large portions of the code and integrating the
contributions of the community. contributions of the community.
* Ticket triagers: anyone in the Django community who chooses to * Ticket triagers: anyone in the Django community who chooses to
become involved in Django's development process. Our Trac installation become involved in Django's development process. Our Trac installation
is intentionally left open to the public, and anyone can triage tickets. is intentionally left open to the public, and anyone can triage tickets.
Django is a community project, and we encourage :ref:`triage by the Django is a community project, and we encourage :ref:`triage by the
community<how-can-i-help-with-triaging>`. community<how-can-i-help-with-triaging>`.
By way of example, here we see the lifecycle of an average ticket: By way of example, here we see the lifecycle of an average ticket:
@ -185,36 +185,40 @@ Other triage attributes
A number of flags, appearing as checkboxes in Trac, can be set on a ticket: A number of flags, appearing as checkboxes in Trac, can be set on a ticket:
* Has patch * Has patch
This means the ticket has an associated This means the ticket has an associated
:doc:`patch<writing-code/submitting-patches>`. These will be reviewed :doc:`patch<writing-code/submitting-patches>`. These will be reviewed
to see if the patch is "good". to see if the patch is "good".
* Needs documentation:
This flag is used for tickets with patches that need associated * Needs documentation:
documentation. Complete documentation of features is a prerequisite This flag is used for tickets with patches that need associated
before we can check them into the codebase. documentation. Complete documentation of features is a prerequisite
* Needs tests before we can check them into the codebase.
This flags the patch as needing associated unit tests. Again, this
is a required part of a valid patch. * Needs tests
* Patch needs improvement This flags the patch as needing associated unit tests. Again, this
This flag means that although the ticket *has* a patch, it's not quite is a required part of a valid patch.
ready for checkin. This could mean the patch no longer applies
cleanly, there is a flaw in the implementation, or that the code * Patch needs improvement
doesn't meet our standards. This flag means that although the ticket *has* a patch, it's not quite
* Easy pickings ready for checkin. This could mean the patch no longer applies
Tickets that would require small, easy, patches. cleanly, there is a flaw in the implementation, or that the code
doesn't meet our standards.
* Easy pickings
Tickets that would require small, easy, patches.
Tickets should be categorized by *type* between: Tickets should be categorized by *type* between:
* New Feature * New Feature
For adding something new. For adding something new.
* Bug * Bug
For when an existing thing is broken or not behaving as expected. For when an existing thing is broken or not behaving as expected.
* Cleanup/optimization * Cleanup/optimization
For when nothing is broken but something could be made cleaner, For when nothing is broken but something could be made cleaner,
better, faster, stronger. better, faster, stronger.
Tickets should also be classified into *components* indicating which area of Tickets should also be classified into *components* indicating which area of
the Django codebase they belong to. This makes tickets better organized and the Django codebase they belong to. This makes tickets better organized and
@ -243,57 +247,57 @@ leave a comment with your thoughts instead.
If you do close a ticket, you should always make sure of the following: If you do close a ticket, you should always make sure of the following:
* Be certain that the issue is resolved. * Be certain that the issue is resolved.
* Leave a comment explaining the decision to close the ticket. * Leave a comment explaining the decision to close the ticket.
* If there is a way they can improve the ticket to reopen it, let them know. * If there is a way they can improve the ticket to reopen it, let them know.
* If the ticket is a duplicate, reference the original ticket. Also * If the ticket is a duplicate, reference the original ticket. Also
cross-reference the closed ticket by leaving a comment in the original one cross-reference the closed ticket by leaving a comment in the original one
-- this allows to access more related information about the reported bug -- this allows to access more related information about the reported bug
or requested feature. or requested feature.
* **Be polite.** No one likes having their ticket closed. It can be * **Be polite.** No one likes having their ticket closed. It can be
frustrating or even discouraging. The best way to avoid turning people frustrating or even discouraging. The best way to avoid turning people
off from contributing to Django is to be polite and friendly and to offer off from contributing to Django is to be polite and friendly and to offer
suggestions for how they could improve this ticket and other tickets in suggestions for how they could improve this ticket and other tickets in
the future. the future.
A ticket can be resolved in a number of ways: A ticket can be resolved in a number of ways:
* fixed * fixed
Used by the core developers once a patch has been rolled into Used by the core developers once a patch has been rolled into
Django and the issue is fixed. Django and the issue is fixed.
* invalid * invalid
Used if the ticket is found to be incorrect. This means that the Used if the ticket is found to be incorrect. This means that the
issue in the ticket is actually the result of a user error, or issue in the ticket is actually the result of a user error, or
describes a problem with something other than Django, or isn't describes a problem with something other than Django, or isn't
a bug report or feature request at all (for example, some new users a bug report or feature request at all (for example, some new users
submit support queries as tickets). submit support queries as tickets).
* wontfix * wontfix
Used when a core developer decides that this request is not Used when a core developer decides that this request is not
appropriate for consideration in Django. This is usually chosen after appropriate for consideration in Django. This is usually chosen after
discussion in the `django-developers`_ mailing list. Feel free to discussion in the `django-developers`_ mailing list. Feel free to
start or join in discussions of "wontfix" tickets on the start or join in discussions of "wontfix" tickets on the
django-developers_ mailing list, but please do not reopen tickets django-developers_ mailing list, but please do not reopen tickets
closed as "wontfix" by a :doc:`core developer</internals/committers>`. closed as "wontfix" by a :doc:`core developer</internals/committers>`.
* duplicate * duplicate
Used when another ticket covers the same issue. By closing duplicate Used when another ticket covers the same issue. By closing duplicate
tickets, we keep all the discussion in one place, which helps tickets, we keep all the discussion in one place, which helps
everyone. everyone.
* worksforme * worksforme
Used when the ticket doesn't contain enough detail to replicate Used when the ticket doesn't contain enough detail to replicate
the original bug. the original bug.
* needsinfo * needsinfo
Used when the ticket does not contain enough information to replicate Used when the ticket does not contain enough information to replicate
the reported issue but is potentially still valid. The ticket the reported issue but is potentially still valid. The ticket
should be reopened when more information is supplied. should be reopened when more information is supplied.
If you believe that the ticket was closed in error -- because you're If you believe that the ticket was closed in error -- because you're
still having the issue, or it's popped up somewhere else, or the triagers have still having the issue, or it's popped up somewhere else, or the triagers have
@ -315,39 +319,39 @@ forgotten your password, you can reset it using the `password reset page`_.
Then, you can help out by: Then, you can help out by:
* Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate." * Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate."
* Promoting "Unreviewed" tickets to "Design decision needed" if a design * Promoting "Unreviewed" tickets to "Design decision needed" if a design
decision needs to be made, or "Accepted" in case of obvious bugs or decision needs to be made, or "Accepted" in case of obvious bugs or
sensible, clearly defined, feature requests. sensible, clearly defined, feature requests.
* Correcting the "Needs tests", "Needs documentation", or "Has patch" * Correcting the "Needs tests", "Needs documentation", or "Has patch"
flags for tickets where they are incorrectly set. flags for tickets where they are incorrectly set.
* Setting the "`Easy pickings`_" flag for tickets that are small and * Setting the "`Easy pickings`_" flag for tickets that are small and
relatively straightforward. relatively straightforward.
* Checking that old tickets are still valid. If a ticket hasn't seen * Checking that old tickets are still valid. If a ticket hasn't seen
any activity in a long time, it's possible that the problem has been any activity in a long time, it's possible that the problem has been
fixed but the ticket hasn't yet been closed. fixed but the ticket hasn't yet been closed.
* Contacting the owners of tickets that have been claimed but have not * Contacting the owners of tickets that have been claimed but have not
seen any recent activity. If the owner doesn't respond after a week seen any recent activity. If the owner doesn't respond after a week
or so, remove the owner's claim on the ticket. or so, remove the owner's claim on the ticket.
* Identifying trends and themes in the tickets. If there a lot of bug * Identifying trends and themes in the tickets. If there a lot of bug
reports about a particular part of Django, it may indicate we should reports about a particular part of Django, it may indicate we should
consider refactoring that part of the code. If a trend is emerging, consider refactoring that part of the code. If a trend is emerging,
you should raise it for discussion (referencing the relevant tickets) you should raise it for discussion (referencing the relevant tickets)
on `django-developers`_. on `django-developers`_.
* Set the *type* of tickets that are still uncategorized. * Set the *type* of tickets that are still uncategorized.
* Verify if patches submitted by other users are correct. If they do and * Verify if patches submitted by other users are correct. If they do and
also contain appropriate documentation and tests then move them to the also contain appropriate documentation and tests then move them to the
"Ready for Checkin" stage. If they don't then leave a comment to explain "Ready for Checkin" stage. If they don't then leave a comment to explain
why and set the corresponding flags ("Patch needs improvement", why and set the corresponding flags ("Patch needs improvement",
"Needs tests" etc.). "Needs tests" etc.).
.. note:: .. note::
@ -362,23 +366,23 @@ Then, you can help out by:
However, we do ask the following of all general community members working in However, we do ask the following of all general community members working in
the ticket database: the ticket database:
* Please **don't** close tickets as "wontfix." The core developers will * Please **don't** close tickets as "wontfix." The core developers will
make the final determination of the fate of a ticket, usually after make the final determination of the fate of a ticket, usually after
consultation with the community. consultation with the community.
* Please **don't** promote your own tickets to "Ready for checkin". You * Please **don't** promote your own tickets to "Ready for checkin". You
may mark other people's tickets which you've reviewed as "Ready for may mark other people's tickets which you've reviewed as "Ready for
checkin", but you should get at minimum one other community member to checkin", but you should get at minimum one other community member to
review a patch that you submit. review a patch that you submit.
* Please **don't** reverse a decision that has been made by a :doc:`core * Please **don't** reverse a decision that has been made by a :doc:`core
developer</internals/committers>`. If you disagree with a decision that developer</internals/committers>`. If you disagree with a decision that
has been made, please post a message to `django-developers`_. has been made, please post a message to `django-developers`_.
* If you're unsure if you should be making a change, don't make the * If you're unsure if you should be making a change, don't make the
change but instead leave a comment with your concerns on the ticket, change but instead leave a comment with your concerns on the ticket,
or post a message to `django-developers`_. It's okay to be unsure, or post a message to `django-developers`_. It's okay to be unsure,
but your input is still valuable. but your input is still valuable.
.. _Trac: http://code.djangoproject.com/ .. _Trac: http://code.djangoproject.com/
.. _django-developers: http://groups.google.com/group/django-developers .. _django-developers: http://groups.google.com/group/django-developers

View File

@ -14,31 +14,31 @@ take more than a single patch, or requires large-scale refactoring -- you need
to do it on a feature branch. Our development process recognizes two options to do it on a feature branch. Our development process recognizes two options
for feature branches: for feature branches:
1. Feature branches using a distributed revision control system like 1. Feature branches using a distributed revision control system like
Git_, Mercurial_, Bazaar_, etc. Git_, Mercurial_, Bazaar_, etc.
If you're familiar with one of these tools, this is probably your best If you're familiar with one of these tools, this is probably your best
option since it doesn't require any support or buy-in from the Django option since it doesn't require any support or buy-in from the Django
core developers. core developers.
However, do keep in mind that Django will continue to use Subversion However, do keep in mind that Django will continue to use Subversion
for the foreseeable future, and this will naturally limit the for the foreseeable future, and this will naturally limit the
recognition of your branch. Further, if your branch becomes eligible recognition of your branch. Further, if your branch becomes eligible
for merging to trunk you'll need to find a core developer familiar for merging to trunk you'll need to find a core developer familiar
with your DVCS of choice who'll actually perform the merge. with your DVCS of choice who'll actually perform the merge.
If you do decided to start a distributed branch of Django and choose to If you do decided to start a distributed branch of Django and choose to
make it public, please add the branch to the `Django branches`_ wiki make it public, please add the branch to the `Django branches`_ wiki
page. page.
2. Feature branches using SVN have a higher bar. If you want a branch 2. Feature branches using SVN have a higher bar. If you want a branch
in SVN itself, you'll need a "mentor" among the :doc:`core committers in SVN itself, you'll need a "mentor" among the :doc:`core committers
</internals/committers>`. This person is responsible for actually </internals/committers>`. This person is responsible for actually
creating the branch, monitoring your process (see below), and creating the branch, monitoring your process (see below), and
ultimately merging the branch into trunk. ultimately merging the branch into trunk.
If you want a feature branch in SVN, you'll need to ask in If you want a feature branch in SVN, you'll need to ask in
`django-developers`_ for a mentor. `django-developers`_ for a mentor.
.. _git: http://git-scm.com/ .. _git: http://git-scm.com/
.. _mercurial: http://mercurial.selenic.com/ .. _mercurial: http://mercurial.selenic.com/
@ -60,21 +60,21 @@ Developers with branches in SVN, however, **must** follow these rules. The
branch mentor will keep on eye on the branch and **will delete it** if these branch mentor will keep on eye on the branch and **will delete it** if these
rules are broken. rules are broken.
* Only branch entire copies of the Django tree, even if work is only * Only branch entire copies of the Django tree, even if work is only
happening on part of that tree. This makes it painless to switch to a happening on part of that tree. This makes it painless to switch to a
branch. branch.
* Merge changes from trunk no less than once a week, and preferably every * Merge changes from trunk no less than once a week, and preferably every
couple-three days. couple-three days.
In our experience, doing regular trunk merges is often the difference In our experience, doing regular trunk merges is often the difference
between a successful branch and one that fizzles and dies. between a successful branch and one that fizzles and dies.
If you're working on an SVN branch, you should be using `svnmerge.py`_ If you're working on an SVN branch, you should be using `svnmerge.py`_
to track merges from trunk. to track merges from trunk.
* Keep tests passing and documentation up-to-date. As with patches, * Keep tests passing and documentation up-to-date. As with patches,
we'll only merge a branch that comes with tests and documentation. we'll only merge a branch that comes with tests and documentation.
.. _svnmerge.py: http://www.orcaware.com/svn/wiki/Svnmerge.py .. _svnmerge.py: http://www.orcaware.com/svn/wiki/Svnmerge.py
@ -91,11 +91,11 @@ Using branches
To use a branch, you'll need to do two things: To use a branch, you'll need to do two things:
* Get the branch's code through Subversion. * Get the branch's code through Subversion.
* Point your Python ``site-packages`` directory at the branch's version of * Point your Python ``site-packages`` directory at the branch's version of
the ``django`` package rather than the version you already have the ``django`` package rather than the version you already have
installed. installed.
Getting the code from Subversion Getting the code from Subversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -7,137 +7,137 @@ Please follow these coding standards when writing code for inclusion in Django.
Python style Python style
------------ ------------
* Unless otherwise specified, follow :pep:`8`. * Unless otherwise specified, follow :pep:`8`.
You could use a tool like `pep8`_ to check for some problems in this You could use a tool like `pep8`_ to check for some problems in this
area, but remember that :pep:`8` is only a guide, so respect the style of area, but remember that :pep:`8` is only a guide, so respect the style of
the surrounding code as a primary goal. the surrounding code as a primary goal.
* Use four spaces for indentation. * Use four spaces for indentation.
* Use underscores, not camelCase, for variable, function and method names * Use underscores, not camelCase, for variable, function and method names
(i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``). (i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``).
* Use ``InitialCaps`` for class names (or for factory functions that * Use ``InitialCaps`` for class names (or for factory functions that
return classes). return classes).
* In docstrings, use "action words" such as:: * In docstrings, use "action words" such as::
def foo(): def foo():
""" """
Calculates something and returns the result. Calculates something and returns the result.
""" """
pass pass
Here's an example of what not to do:: Here's an example of what not to do::
def foo(): def foo():
""" """
Calculate something and return the result. Calculate something and return the result.
""" """
pass pass
Template style Template style
-------------- --------------
* In Django template code, put one (and only one) space between the curly * In Django template code, put one (and only one) space between the curly
brackets and the tag contents. brackets and the tag contents.
Do this: Do this:
.. code-block:: html+django .. code-block:: html+django
{{ foo }} {{ foo }}
Don't do this: Don't do this:
.. code-block:: html+django .. code-block:: html+django
{{foo}} {{foo}}
View style View style
---------- ----------
* In Django views, the first parameter in a view function should be called * In Django views, the first parameter in a view function should be called
``request``. ``request``.
Do this:: Do this::
def my_view(request, foo): def my_view(request, foo):
# ... # ...
Don't do this:: Don't do this::
def my_view(req, foo): def my_view(req, foo):
# ... # ...
Model style Model style
----------- -----------
* Field names should be all lowercase, using underscores instead of * Field names should be all lowercase, using underscores instead of
camelCase. camelCase.
Do this:: Do this::
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=20) first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40) last_name = models.CharField(max_length=40)
Don't do this:: Don't do this::
class Person(models.Model): class Person(models.Model):
FirstName = models.CharField(max_length=20) FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40) Last_Name = models.CharField(max_length=40)
* The ``class Meta`` should appear *after* the fields are defined, with * The ``class Meta`` should appear *after* the fields are defined, with
a single blank line separating the fields and the class definition. a single blank line separating the fields and the class definition.
Do this:: Do this::
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=20) first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40) last_name = models.CharField(max_length=40)
class Meta: class Meta:
verbose_name_plural = 'people' verbose_name_plural = 'people'
Don't do this:: Don't do this::
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=20) first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40) last_name = models.CharField(max_length=40)
class Meta: class Meta:
verbose_name_plural = 'people' verbose_name_plural = 'people'
Don't do this, either:: Don't do this, either::
class Person(models.Model): class Person(models.Model):
class Meta: class Meta:
verbose_name_plural = 'people' verbose_name_plural = 'people'
first_name = models.CharField(max_length=20) first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40) last_name = models.CharField(max_length=40)
* The order of model inner classes and standard methods should be as * The order of model inner classes and standard methods should be as
follows (noting that these are not all required): follows (noting that these are not all required):
* All database fields * All database fields
* Custom manager attributes * Custom manager attributes
* ``class Meta`` * ``class Meta``
* ``def __unicode__()`` * ``def __unicode__()``
* ``def __str__()`` * ``def __str__()``
* ``def save()`` * ``def save()``
* ``def get_absolute_url()`` * ``def get_absolute_url()``
* Any custom methods * Any custom methods
* If ``choices`` is defined for a given model field, define the choices as * If ``choices`` is defined for a given model field, define the choices as
a tuple of tuples, with an all-uppercase name, either near the top of a tuple of tuples, with an all-uppercase name, either near the top of
the model module or just above the model class. Example:: the model module or just above the model class. Example::
GENDER_CHOICES = ( GENDER_CHOICES = (
('M', 'Male'), ('M', 'Male'),
('F', 'Female'), ('F', 'Female'),
) )
Use of ``django.conf.settings`` Use of ``django.conf.settings``
------------------------------- -------------------------------
@ -178,26 +178,26 @@ as :class:`django.utils.functional.LazyObject`,
Miscellaneous Miscellaneous
------------- -------------
* Mark all strings for internationalization; see the :doc:`i18n * Mark all strings for internationalization; see the :doc:`i18n
documentation </topics/i18n/index>` for details. documentation </topics/i18n/index>` for details.
* Remove ``import`` statements that are no longer used when you change code. * Remove ``import`` statements that are no longer used when you change code.
The most common tools for this task are `pyflakes`_ and `pylint`_. The most common tools for this task are `pyflakes`_ and `pylint`_.
* Systematically remove all trailing whitespaces from your code as those * Systematically remove all trailing whitespaces from your code as those
add unnecessary bytes, add visual clutter to the patches and can also add unnecessary bytes, add visual clutter to the patches and can also
occasionally cause unnecessary merge conflicts. Some IDE's can be occasionally cause unnecessary merge conflicts. Some IDE's can be
configured to automatically remove them and most VCS tools can be set to configured to automatically remove them and most VCS tools can be set to
highlight them in diff outputs. Note, however, that patches which only highlight them in diff outputs. Note, however, that patches which only
remove whitespace (or only make changes for nominal PEP 8 conformance) remove whitespace (or only make changes for nominal PEP 8 conformance)
are likely to be rejected, since they only introduce noise rather than are likely to be rejected, since they only introduce noise rather than
code improvement. Tidy up when you're next changing code in the area. code improvement. Tidy up when you're next changing code in the area.
* Please don't put your name in the code you contribute. Our policy is to * Please don't put your name in the code you contribute. Our policy is to
keep contributors' names in the ``AUTHORS`` file distributed with Django keep contributors' names in the ``AUTHORS`` file distributed with Django
-- not scattered throughout the codebase itself. Feel free to include a -- not scattered throughout the codebase itself. Feel free to include a
change to the ``AUTHORS`` file in your patch if you make more than a change to the ``AUTHORS`` file in your patch if you make more than a
single trivial change. single trivial change.
.. _pep8: http://pypi.python.org/pypi/pep8 .. _pep8: http://pypi.python.org/pypi/pep8
.. _pyflakes: http://pypi.python.org/pypi/pyflakes .. _pyflakes: http://pypi.python.org/pypi/pyflakes

View File

@ -19,28 +19,28 @@ If you have identified a contribution you want to make and you're capable of
fixing it (as measured by your coding ability, knowledge of Django internals fixing it (as measured by your coding ability, knowledge of Django internals
and time availability), claim it by following these steps: and time availability), claim it by following these steps:
* `Create an account`_ to use in our ticket system. If you have an account * `Create an account`_ to use in our ticket system. If you have an account
but have forgotten your password, you can reset it using the but have forgotten your password, you can reset it using the
`password reset page`_. `password reset page`_.
* If a ticket for this issue doesn't exist yet, create one in our * If a ticket for this issue doesn't exist yet, create one in our
`ticket tracker`_. `ticket tracker`_.
* If a ticket for this issue already exists, make sure nobody else has * If a ticket for this issue already exists, make sure nobody else has
claimed it. To do this, look at the "Assigned to" section of the ticket. claimed it. To do this, look at the "Assigned to" section of the ticket.
If it's assigned to "nobody," then it's available to be claimed. If it's assigned to "nobody," then it's available to be claimed.
Otherwise, somebody else is working on this ticket, and you either find Otherwise, somebody else is working on this ticket, and you either find
another bug/feature to work on, or contact the developer working on the another bug/feature to work on, or contact the developer working on the
ticket to offer your help. ticket to offer your help.
* Log into your account, if you haven't already, by clicking "Login" in * Log into your account, if you haven't already, by clicking "Login" in
the upper right of the ticket page. the upper right of the ticket page.
* Claim the ticket: * Claim the ticket:
1. click the "accept" radio button under "Action" near the bottom of the 1. click the "accept" radio button under "Action" near the bottom of the
page, page,
2. then click "Submit changes." 2. then click "Submit changes."
.. _Create an account: https://www.djangoproject.com/accounts/register/ .. _Create an account: https://www.djangoproject.com/accounts/register/
.. _password reset page: https://www.djangoproject.com/accounts/password/reset/ .. _password reset page: https://www.djangoproject.com/accounts/password/reset/
@ -76,43 +76,43 @@ it.
Patch style Patch style
----------- -----------
* Make sure your code matches our :doc:`coding-style`. * Make sure your code matches our :doc:`coding-style`.
* Submit patches in the format returned by the ``svn diff`` command. * Submit patches in the format returned by the ``svn diff`` command.
An exception is for code changes that are described more clearly in An exception is for code changes that are described more clearly in
plain English than in code. Indentation is the most common example; it's plain English than in code. Indentation is the most common example; it's
hard to read patches when the only difference in code is that it's hard to read patches when the only difference in code is that it's
indented. indented.
Patches in ``git diff`` format are also acceptable. Patches in ``git diff`` format are also acceptable.
* When creating patches, always run ``svn diff`` from the top-level * When creating patches, always run ``svn diff`` from the top-level
``trunk`` directory -- i.e. the one that contains ``django``, ``docs``, ``trunk`` directory -- i.e. the one that contains ``django``, ``docs``,
``tests``, ``AUTHORS``, etc. This makes it easy for other people to ``tests``, ``AUTHORS``, etc. This makes it easy for other people to
apply your patches. apply your patches.
* Attach patches to a ticket in the `ticket tracker`_, using the "attach * Attach patches to a ticket in the `ticket tracker`_, using the "attach
file" button. Please *don't* put the patch in the ticket description file" button. Please *don't* put the patch in the ticket description
or comment unless it's a single line patch. or comment unless it's a single line patch.
* Name the patch file with a ``.diff`` extension; this will let the ticket * Name the patch file with a ``.diff`` extension; this will let the ticket
tracker apply correct syntax highlighting, which is quite helpful. tracker apply correct syntax highlighting, which is quite helpful.
* Check the "Has patch" box on the ticket details. This will make it * Check the "Has patch" box on the ticket details. This will make it
obvious that the ticket includes a patch, and it will add the ticket to obvious that the ticket includes a patch, and it will add the ticket to
the `list of tickets with patches`_. the `list of tickets with patches`_.
* The code required to fix a problem or add a feature is an essential part * The code required to fix a problem or add a feature is an essential part
of a patch, but it is not the only part. A good patch should also of a patch, but it is not the only part. A good patch should also
include a regression test to validate the behavior that has been fixed include a regression test to validate the behavior that has been fixed
and to prevent the problem from arising again. Also, if some tickets are and to prevent the problem from arising again. Also, if some tickets are
relevant to the code that you've written, mention the ticket numbers in relevant to the code that you've written, mention the ticket numbers in
some comments in the test so that one can easily trace back the relevant some comments in the test so that one can easily trace back the relevant
discussions after your patch gets committed and the tickets get closed. discussions after your patch gets committed and the tickets get closed.
* If the code associated with a patch adds a new feature, or modifies * If the code associated with a patch adds a new feature, or modifies
behavior of an existing feature, the patch should also contain behavior of an existing feature, the patch should also contain
documentation. documentation.
Non-trivial patches Non-trivial patches
------------------- -------------------

View File

@ -7,9 +7,9 @@ code base. It's our policy to make sure all tests pass at all times.
The tests cover: The tests cover:
* Models and the database API (``tests/modeltests``), * Models and the database API (``tests/modeltests``),
* Everything else in core Django code (``tests/regressiontests``), * Everything else in core Django code (``tests/regressiontests``),
* :ref:`contrib-apps` (``django/contrib/<app>/tests``). * :ref:`contrib-apps` (``django/contrib/<app>/tests``).
We appreciate any and all contributions to the test suite! We appreciate any and all contributions to the test suite!
@ -58,30 +58,30 @@ and type:
The :setting:`DATABASES` setting in this test settings module needs to define The :setting:`DATABASES` setting in this test settings module needs to define
two databases: two databases:
* A ``default`` database. This database should use the backend that * A ``default`` database. This database should use the backend that
you want to use for primary testing you want to use for primary testing
* A database with the alias ``other``. The ``other`` database is * A database with the alias ``other``. The ``other`` database is
used to establish that queries can be directed to different used to establish that queries can be directed to different
databases. As a result, this database can use any backend you databases. As a result, this database can use any backend you
want. It doesn't need to use the same backend as the ``default`` 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). database (although it can use the same backend if you want to).
If you're using a backend that isn't SQLite, you will need to provide other If you're using a backend that isn't SQLite, you will need to provide other
details for each database: details for each database:
* The :setting:`USER` option for each of your databases needs to * The :setting:`USER` option for each of your databases needs to
specify an existing user account for the database. specify an existing user account for the database.
* The :setting:`PASSWORD` option needs to provide the password for * The :setting:`PASSWORD` option needs to provide the password for
the :setting:`USER` that has been specified. the :setting:`USER` that has been specified.
* The :setting:`NAME` option 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 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 touch this database; the test runner creates a new database whose name
is :setting:`NAME` prefixed with ``test_``, and this test database is is :setting:`NAME` prefixed with ``test_``, and this test database is
deleted when the tests are finished. This means your user account needs deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``. permission to execute ``CREATE DATABASE``.
You will also need to ensure that your database uses UTF-8 as the default 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, character set. If your database server doesn't use UTF-8 as a default charset,
@ -128,13 +128,13 @@ Running all the tests
If you want to run the full suite of tests, you'll need to install a number of If you want to run the full suite of tests, you'll need to install a number of
dependencies: dependencies:
* PyYAML_ * PyYAML_
* Markdown_ * Markdown_
* Textile_ * Textile_
* Docutils_ * Docutils_
* setuptools_ * setuptools_
* memcached_, plus a :ref:`supported Python binding <memcached>` * memcached_, plus a :ref:`supported Python binding <memcached>`
* gettext_ (:ref:`gettext_on_windows`) * gettext_ (:ref:`gettext_on_windows`)
If you want to test the memcached cache backend, you'll also need to define If you want to test the memcached cache backend, you'll also need to define
a :setting:`CACHES` setting that points at your memcached instance. a :setting:`CACHES` setting that points at your memcached instance.

View File

@ -9,11 +9,11 @@ possible.
Documentation changes generally come in two forms: Documentation changes generally come in two forms:
* General improvements: typo corrections, error fixes and better * General improvements: typo corrections, error fixes and better
explanations through clearer writing and more examples. explanations through clearer writing and more examples.
* New features: documentation of features that have been added to the * New features: documentation of features that have been added to the
framework since the last release. framework since the last release.
This section explains how writers can craft their documentation changes This section explains how writers can craft their documentation changes
in the most useful and least error-prone ways. in the most useful and least error-prone ways.
@ -54,37 +54,37 @@ Commonly used terms
Here are some style guidelines on commonly used terms throughout the Here are some style guidelines on commonly used terms throughout the
documentation: documentation:
* **Django** -- when referring to the framework, capitalize Django. It is * **Django** -- when referring to the framework, capitalize Django. It is
lowercase only in Python code and in the djangoproject.com logo. lowercase only in Python code and in the djangoproject.com logo.
* **email** -- no hyphen. * **email** -- no hyphen.
* **MySQL**, **PostgreSQL**, **SQLite** * **MySQL**, **PostgreSQL**, **SQLite**
* **Python** -- when referring to the language, capitalize Python. * **Python** -- when referring to the language, capitalize Python.
* **realize**, **customize**, **initialize**, etc. -- use the American * **realize**, **customize**, **initialize**, etc. -- use the American
"ize" suffix, not "ise." "ize" suffix, not "ise."
* **subclass** -- it's a single word without a hyphen, both as a verb * **subclass** -- it's a single word without a hyphen, both as a verb
("subclass that model") and as a noun ("create a subclass"). ("subclass that model") and as a noun ("create a subclass").
* **Web**, **World Wide Web**, **the Web** -- note Web is always * **Web**, **World Wide Web**, **the Web** -- note Web is always
capitalized when referring to the World Wide Web. capitalized when referring to the World Wide Web.
* **Web site** -- use two words, with Web capitalized. * **Web site** -- use two words, with Web capitalized.
Django-specific terminology Django-specific terminology
--------------------------- ---------------------------
* **model** -- it's not capitalized. * **model** -- it's not capitalized.
* **template** -- it's not capitalized. * **template** -- it's not capitalized.
* **URLconf** -- use three capitalized letters, with no space before * **URLconf** -- use three capitalized letters, with no space before
"conf." "conf."
* **view** -- it's not capitalized. * **view** -- it's not capitalized.
Guidelines for reStructuredText files Guidelines for reStructuredText files
------------------------------------- -------------------------------------
@ -92,27 +92,27 @@ Guidelines for reStructuredText files
These guidelines regulate the format of our reST (reStructuredText) These guidelines regulate the format of our reST (reStructuredText)
documentation: documentation:
* In section titles, capitalize only initial words and proper nouns. * In section titles, capitalize only initial words and proper nouns.
* Wrap the documentation at 80 characters wide, unless a code example * Wrap the documentation at 80 characters wide, unless a code example
is significantly less readable when split over two lines, or for another is significantly less readable when split over two lines, or for another
good reason. good reason.
* The main thing to keep in mind as you write and edit docs is that the * The main thing to keep in mind as you write and edit docs is that the
more semantic markup you can add the better. So:: more semantic markup you can add the better. So::
Add ``django.contrib.auth`` to your ``INSTALLED_APPS``... Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...
Isn't nearly as helpful as:: Isn't nearly as helpful as::
Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`... Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...
This is because Sphinx will generate proper links for the latter, which This is because Sphinx will generate proper links for the latter, which
greatly helps readers. There's basically no limit to the amount of greatly helps readers. There's basically no limit to the amount of
useful markup you can add. useful markup you can add.
* Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx' * Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx'
documentation. documentation.
Django-specific markup Django-specific markup
---------------------- ----------------------
@ -122,41 +122,41 @@ description units:
__ http://sphinx.pocoo.org/markup/desc.html __ http://sphinx.pocoo.org/markup/desc.html
* Settings:: * Settings::
.. setting:: INSTALLED_APPS .. setting:: INSTALLED_APPS
To link to a setting, use ``:setting:`INSTALLED_APPS```. To link to a setting, use ``:setting:`INSTALLED_APPS```.
* Template tags:: * Template tags::
.. templatetag:: regroup .. templatetag:: regroup
To link, use ``:ttag:`regroup```. To link, use ``:ttag:`regroup```.
* Template filters:: * Template filters::
.. templatefilter:: linebreaksbr .. templatefilter:: linebreaksbr
To link, use ``:tfilter:`linebreaksbr```. To link, use ``:tfilter:`linebreaksbr```.
* Field lookups (i.e. ``Foo.objects.filter(bar__exact=whatever)``):: * Field lookups (i.e. ``Foo.objects.filter(bar__exact=whatever)``)::
.. fieldlookup:: exact .. fieldlookup:: exact
To link, use ``:lookup:`exact```. To link, use ``:lookup:`exact```.
* ``django-admin`` commands:: * ``django-admin`` commands::
.. django-admin:: syncdb .. django-admin:: syncdb
To link, use ``:djadmin:`syncdb```. To link, use ``:djadmin:`syncdb```.
* ``django-admin`` command-line options:: * ``django-admin`` command-line options::
.. django-admin-option:: --traceback .. django-admin-option:: --traceback
To link, use ``:djadminopt:`--traceback```. To link, use ``:djadminopt:`--traceback```.
.. _documenting-new-features: .. _documenting-new-features:
@ -184,68 +184,68 @@ An example
For a quick example of how it all fits together, consider this hypothetical For a quick example of how it all fits together, consider this hypothetical
example: example:
* First, the ``ref/settings.txt`` document could have an overall layout * First, the ``ref/settings.txt`` document could have an overall layout
like this: like this:
.. code-block:: rst .. code-block:: rst
======== ========
Settings Settings
======== ========
... ...
.. _available-settings: .. _available-settings:
Available settings Available settings
================== ==================
... ...
.. _deprecated-settings: .. _deprecated-settings:
Deprecated settings Deprecated settings
=================== ===================
... ...
* Next, the ``topics/settings.txt`` document could contain something like * Next, the ``topics/settings.txt`` document could contain something like
this: this:
.. code-block:: rst .. code-block:: rst
You can access a :ref:`listing of all available settings You can access a :ref:`listing of all available settings
<available-settings>`. For a list of deprecated settings see <available-settings>`. For a list of deprecated settings see
:ref:`deprecated-settings`. :ref:`deprecated-settings`.
You can find both in the :doc:`settings reference document You can find both in the :doc:`settings reference document
</ref/settings>`. </ref/settings>`.
We use the Sphinx :rst:role:`doc` cross reference element when we want to We use the Sphinx :rst:role:`doc` cross reference element when we want to
link to another document as a whole and the :rst:role:`ref` element when link to another document as a whole and the :rst:role:`ref` element when
we want to link to an arbitrary location in a document. we want to link to an arbitrary location in a document.
* Next, notice how the settings are annotated: * Next, notice how the settings are annotated:
.. code-block:: rst .. code-block:: rst
.. setting:: ADMIN_FOR .. setting:: ADMIN_FOR
ADMIN_FOR ADMIN_FOR
--------- ---------
Default: ``()`` (Empty tuple) Default: ``()`` (Empty tuple)
Used for admin-site settings modules, this should be a tuple of Used for admin-site settings modules, this should be a tuple of
settings modules (in the format ``'foo.bar.baz'``) for which this site settings modules (in the format ``'foo.bar.baz'``) for which this site
is an admin. is an admin.
The admin site uses this in its automatically-introspected The admin site uses this in its automatically-introspected
documentation of models, views and template tags. documentation of models, views and template tags.
This marks up the following header as the "canonical" target for the This marks up the following header as the "canonical" target for the
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``, setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``,
I can reference it using ``:setting:`ADMIN_FOR```. I can reference it using ``:setting:`ADMIN_FOR```.
That's basically how everything fits together. That's basically how everything fits together.
@ -257,57 +257,57 @@ Improving the documentation
A few small improvements can be made to make the documentation read and A few small improvements can be made to make the documentation read and
look better: look better:
* Most of the various ``index.txt`` documents have *very* short or even * Most of the various ``index.txt`` documents have *very* short or even
non-existent intro text. Each of those documents needs a good short non-existent intro text. Each of those documents needs a good short
intro the content below that point. intro the content below that point.
* The glossary is very perfunctory. It needs to be filled out. * The glossary is very perfunctory. It needs to be filled out.
* Add more metadata targets. Lots of places look like:: * Add more metadata targets. Lots of places look like::
``File.close()`` ``File.close()``
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
\... these should be:: \... these should be::
.. method:: File.close() .. method:: File.close()
That is, use metadata instead of titles. That is, use metadata instead of titles.
* Add more links -- nearly everything that's an inline code literal * Add more links -- nearly everything that's an inline code literal
right now can probably be turned into a xref. right now can probably be turned into a xref.
See the ``literals_to_xrefs.py`` file in ``_ext`` -- it's a shell script See the ``literals_to_xrefs.py`` file in ``_ext`` -- it's a shell script
to help do this work. to help do this work.
This will probably be a continuing, never-ending project. This will probably be a continuing, never-ending project.
* Add `info field lists`__ where appropriate. * Add `info field lists`__ where appropriate.
__ http://sphinx.pocoo.org/markup/desc.html#info-field-lists __ http://sphinx.pocoo.org/markup/desc.html#info-field-lists
* Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead * Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead
of ````ADMIN_FOR````. of ````ADMIN_FOR````.
* Use directives where appropriate. Some directives * Use directives where appropriate. Some directives
(e.g. ``.. setting::``) are prefix-style directives; they go *before* (e.g. ``.. setting::``) are prefix-style directives; they go *before*
the unit they're describing. These are known as "crossref" directives. the unit they're describing. These are known as "crossref" directives.
Others (e.g. ``.. class::``) generate their own markup; these should go Others (e.g. ``.. class::``) generate their own markup; these should go
inside the section they're describing. These are called inside the section they're describing. These are called
"description units". "description units".
You can tell which are which by looking at in You can tell which are which by looking at in
:file:`_ext/djangodocs.py`; it registers roles as one of the other. :file:`_ext/djangodocs.py`; it registers roles as one of the other.
* Add ``.. code-block:: <lang>`` to literal blocks so that they get * Add ``.. code-block:: <lang>`` to literal blocks so that they get
highlighted. highlighted.
* When referring to classes/functions/modules, etc., you'll want to use * When referring to classes/functions/modules, etc., you'll want to use
the fully-qualified name of the target the fully-qualified name of the target
(``:class:`django.contrib.contenttypes.models.ContentType```). (``:class:`django.contrib.contenttypes.models.ContentType```).
Since this doesn't look all that awesome in the output -- it shows the Since this doesn't look all that awesome in the output -- it shows the
entire path to the object -- you can prefix the target with a ``~`` entire path to the object -- you can prefix the target with a ``~``
(that's a tilde) to get just the "last bit" of that path. So (that's a tilde) to get just the "last bit" of that path. So
``:class:`~django.contrib.contenttypes.models.ContentType``` will just ``:class:`~django.contrib.contenttypes.models.ContentType``` will just
display a link with the title "ContentType". display a link with the title "ContentType".

View File

@ -13,13 +13,13 @@ about each item can often be found in the release notes of two versions prior.
See the :doc:`Django 1.1 release notes</releases/1.1>` for more details on See the :doc:`Django 1.1 release notes</releases/1.1>` for more details on
these changes. these changes.
* ``AdminSite.root()``. This method of hooking up the admin URLs will be * ``AdminSite.root()``. This method of hooking up the admin URLs will be
removed in favor of including ``admin.site.urls``. removed in favor of including ``admin.site.urls``.
* Authentication backends need to define the boolean attributes * Authentication backends need to define the boolean attributes
``supports_object_permissions`` and ``supports_anonymous_user`` until ``supports_object_permissions`` and ``supports_anonymous_user`` until
version 1.4, at which point it will be assumed that all backends will version 1.4, at which point it will be assumed that all backends will
support these options. support these options.
1.4 1.4
--- ---
@ -27,92 +27,92 @@ these changes.
See the :doc:`Django 1.2 release notes</releases/1.2>` for more details on See the :doc:`Django 1.2 release notes</releases/1.2>` for more details on
these changes. these changes.
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed. Use * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed. Use
the {% csrf_token %} template tag inside forms to enable CSRF the {% csrf_token %} template tag inside forms to enable CSRF
protection. ``CsrfViewMiddleware`` remains and is enabled by default. protection. ``CsrfViewMiddleware`` remains and is enabled by default.
* The old imports for CSRF functionality (``django.contrib.csrf.*``), * The old imports for CSRF functionality (``django.contrib.csrf.*``),
which moved to core in 1.2, will be removed. which moved to core in 1.2, will be removed.
* The :mod:`django.contrib.gis.db.backend` module will be removed in favor * The :mod:`django.contrib.gis.db.backend` module will be removed in favor
of the specific backends. of the specific backends.
* ``SMTPConnection`` will be removed in favor of a generic E-mail backend API. * ``SMTPConnection`` will be removed in favor of a generic E-mail backend API.
* The many to many SQL generation functions on the database backends * The many to many SQL generation functions on the database backends
will be removed. will be removed.
* The ability to use the ``DATABASE_*`` family of top-level settings to * The ability to use the ``DATABASE_*`` family of top-level settings to
define database connections will be removed. define database connections will be removed.
* The ability to use shorthand notation to specify a database backend * The ability to use shorthand notation to specify a database backend
(i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be (i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be
removed. removed.
* The ``get_db_prep_save``, ``get_db_prep_value`` and * The ``get_db_prep_save``, ``get_db_prep_value`` and
``get_db_prep_lookup`` methods will have to support multiple databases. ``get_db_prep_lookup`` methods will have to support multiple databases.
* The ``Message`` model (in ``django.contrib.auth``), its related * The ``Message`` model (in ``django.contrib.auth``), its related
manager in the ``User`` model (``user.message_set``), and the manager in the ``User`` model (``user.message_set``), and the
associated methods (``user.message_set.create()`` and associated methods (``user.message_set.create()`` and
``user.get_and_delete_messages()``), will be removed. The ``user.get_and_delete_messages()``), will be removed. The
:doc:`messages framework </ref/contrib/messages>` should be used :doc:`messages framework </ref/contrib/messages>` should be used
instead. The related ``messages`` variable returned by the instead. The related ``messages`` variable returned by the
auth context processor will also be removed. Note that this auth context processor will also be removed. Note that this
means that the admin application will depend on the messages means that the admin application will depend on the messages
context processor. context processor.
* Authentication backends will need to support the ``obj`` parameter for * Authentication backends will need to support the ``obj`` parameter for
permission checking. The ``supports_object_permissions`` attribute permission checking. The ``supports_object_permissions`` attribute
will no longer be checked and can be removed from custom backends. will no longer be checked and can be removed from custom backends.
* Authentication backends will need to support the ``AnonymousUser`` class * Authentication backends will need to support the ``AnonymousUser`` class
being passed to all methods dealing with permissions. The being passed to all methods dealing with permissions. The
``supports_anonymous_user`` variable will no longer be checked and can be ``supports_anonymous_user`` variable will no longer be checked and can be
removed from custom backends. removed from custom backends.
* The ability to specify a callable template loader rather than a * The ability to specify a callable template loader rather than a
``Loader`` class will be removed, as will the ``load_template_source`` ``Loader`` class will be removed, as will the ``load_template_source``
functions that are included with the built in template loaders for functions that are included with the built in template loaders for
backwards compatibility. backwards compatibility.
* ``django.utils.translation.get_date_formats()`` and * ``django.utils.translation.get_date_formats()`` and
``django.utils.translation.get_partial_date_formats()``. These functions ``django.utils.translation.get_partial_date_formats()``. These functions
will be removed; use the locale-aware will be removed; use the locale-aware
``django.utils.formats.get_format()`` to get the appropriate formats. ``django.utils.formats.get_format()`` to get the appropriate formats.
* In ``django.forms.fields``, the constants: ``DEFAULT_DATE_INPUT_FORMATS``, * In ``django.forms.fields``, the constants: ``DEFAULT_DATE_INPUT_FORMATS``,
``DEFAULT_TIME_INPUT_FORMATS`` and ``DEFAULT_TIME_INPUT_FORMATS`` and
``DEFAULT_DATETIME_INPUT_FORMATS`` will be removed. Use ``DEFAULT_DATETIME_INPUT_FORMATS`` will be removed. Use
``django.utils.formats.get_format()`` to get the appropriate ``django.utils.formats.get_format()`` to get the appropriate
formats. formats.
* The ability to use a function-based test runners will be removed, * The ability to use a function-based test runners will be removed,
along with the ``django.test.simple.run_tests()`` test runner. along with the ``django.test.simple.run_tests()`` test runner.
* The ``views.feed()`` view and ``feeds.Feed`` class in * The ``views.feed()`` view and ``feeds.Feed`` class in
``django.contrib.syndication`` will be removed. The class-based view ``django.contrib.syndication`` will be removed. The class-based view
``views.Feed`` should be used instead. ``views.Feed`` should be used instead.
* ``django.core.context_processors.auth``. This release will * ``django.core.context_processors.auth``. This release will
remove the old method in favor of the new method in remove the old method in favor of the new method in
``django.contrib.auth.context_processors.auth``. ``django.contrib.auth.context_processors.auth``.
* The ``postgresql`` database backend will be removed, use the * The ``postgresql`` database backend will be removed, use the
``postgresql_psycopg2`` backend instead. ``postgresql_psycopg2`` backend instead.
* The ``no`` language code will be removed and has been replaced by the * The ``no`` language code will be removed and has been replaced by the
``nb`` language code. ``nb`` language code.
* Authentication backends will need to define the boolean attribute * Authentication backends will need to define the boolean attribute
``supports_inactive_user`` until version 1.5 when it will be assumed that ``supports_inactive_user`` until version 1.5 when it will be assumed that
all backends will handle inactive users. all backends will handle inactive users.
* ``django.db.models.fields.XMLField`` will be removed. This was * ``django.db.models.fields.XMLField`` will be removed. This was
deprecated as part of the 1.3 release. An accelerated deprecation deprecated as part of the 1.3 release. An accelerated deprecation
schedule has been used because the field hasn't performed any role schedule has been used because the field hasn't performed any role
beyond that of a simple ``TextField`` since the removal of oldforms. beyond that of a simple ``TextField`` since the removal of oldforms.
All uses of ``XMLField`` can be replaced with ``TextField``. All uses of ``XMLField`` can be replaced with ``TextField``.
1.5 1.5
@ -121,67 +121,67 @@ these changes.
See the :doc:`Django 1.3 release notes</releases/1.3>` for more details on See the :doc:`Django 1.3 release notes</releases/1.3>` for more details on
these changes. these changes.
* The ``mod_python`` request handler will be removed. The ``mod_wsgi`` * The ``mod_python`` request handler will be removed. The ``mod_wsgi``
handler should be used instead. handler should be used instead.
* The ``template`` attribute on :class:`~django.test.client.Response` * The ``template`` attribute on :class:`~django.test.client.Response`
objects returned by the :ref:`test client <test-client>` will be removed. objects returned by the :ref:`test client <test-client>` will be removed.
The :attr:`~django.test.client.Response.templates` attribute should be The :attr:`~django.test.client.Response.templates` attribute should be
used instead. used instead.
* The :class:`~django.test.simple.DjangoTestRunner` will be removed. * The :class:`~django.test.simple.DjangoTestRunner` will be removed.
Instead use a unittest-native class. The features of the Instead use a unittest-native class. The features of the
:class:`django.test.simple.DjangoTestRunner` (including fail-fast and :class:`django.test.simple.DjangoTestRunner` (including fail-fast and
Ctrl-C test termination) can currently be provided by the unittest-native Ctrl-C test termination) can currently be provided by the unittest-native
:class:`TextTestRunner`. :class:`TextTestRunner`.
* The undocumented function * The undocumented function
:func:`django.contrib.formtools.utils.security_hash` will be removed, :func:`django.contrib.formtools.utils.security_hash` will be removed,
instead use :func:`django.contrib.formtools.utils.form_hmac` instead use :func:`django.contrib.formtools.utils.form_hmac`
* The function-based generic view modules will be removed in favor of their * The function-based generic view modules will be removed in favor of their
class-based equivalents, outlined :doc:`here class-based equivalents, outlined :doc:`here
</topics/generic-views-migration>`: </topics/generic-views-migration>`:
* The :class:`~django.core.servers.basehttp.AdminMediaHandler` will be * The :class:`~django.core.servers.basehttp.AdminMediaHandler` will be
removed. In its place use removed. In its place use
:class:`~django.contrib.staticfiles.handlers.StaticFilesHandler`. :class:`~django.contrib.staticfiles.handlers.StaticFilesHandler`.
* The :ttag:`url` and :ttag:`ssi` template tags will be * The :ttag:`url` and :ttag:`ssi` template tags will be
modified so that the first argument to each tag is a modified so that the first argument to each tag is a
template variable, not an implied string. Until then, the new-style template variable, not an implied string. Until then, the new-style
behavior is provided in the ``future`` template tag library. behavior is provided in the ``future`` template tag library.
* The :djadmin:`reset` and :djadmin:`sqlreset` management commands * The :djadmin:`reset` and :djadmin:`sqlreset` management commands
will be removed. will be removed.
* Authentication backends will need to support an inactive user * Authentication backends will need to support an inactive user
being passed to all methods dealing with permissions. being passed to all methods dealing with permissions.
The ``supports_inactive_user`` attribute will no longer be checked The ``supports_inactive_user`` attribute will no longer be checked
and can be removed from custom backends. and can be removed from custom backends.
* :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise * :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
a :class:`~django.contrib.gis.geos.GEOSException` when called a :class:`~django.contrib.gis.geos.GEOSException` when called
on a geometry with no SRID value. on a geometry with no SRID value.
* :class:`~django.http.CompatCookie` will be removed in favor of * :class:`~django.http.CompatCookie` will be removed in favor of
:class:`~django.http.SimpleCookie`. :class:`~django.http.SimpleCookie`.
* :class:`django.core.context_processors.PermWrapper` and * :class:`django.core.context_processors.PermWrapper` and
:class:`django.core.context_processors.PermLookupDict` will be removed in :class:`django.core.context_processors.PermLookupDict` will be removed in
favor of the corresponding favor of the corresponding
:class:`django.contrib.auth.context_processors.PermWrapper` and :class:`django.contrib.auth.context_processors.PermWrapper` and
:class:`django.contrib.auth.context_processors.PermLookupDict`, :class:`django.contrib.auth.context_processors.PermLookupDict`,
respectively. respectively.
* The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be * The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be
required to end with a trailing slash to ensure there is a consistent required to end with a trailing slash to ensure there is a consistent
way to combine paths in templates. way to combine paths in templates.
* ``django.db.models.fields.URLField.verify_exists`` will be removed. The * ``django.db.models.fields.URLField.verify_exists`` will be removed. The
feature was deprecated in 1.3.1 due to intractable security and feature was deprecated in 1.3.1 due to intractable security and
performance issues and will follow a slightly accelerated deprecation performance issues and will follow a slightly accelerated deprecation
timeframe. timeframe.
1.6 1.6
--- ---
@ -189,73 +189,73 @@ these changes.
See the :doc:`Django 1.4 release notes</releases/1.4>` for more details on See the :doc:`Django 1.4 release notes</releases/1.4>` for more details on
these changes. these changes.
* The compatibility modules ``django.utils.copycompat`` and * The compatibility modules ``django.utils.copycompat`` and
``django.utils.hashcompat`` as well as the functions ``django.utils.hashcompat`` as well as the functions
``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will ``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will
be removed. The Python builtin versions should be used instead. be removed. The Python builtin versions should be used instead.
* The :func:`~django.views.decorators.csrf.csrf_response_exempt` and * The :func:`~django.views.decorators.csrf.csrf_response_exempt` and
:func:`~django.views.decorators.csrf.csrf_view_exempt` decorators will :func:`~django.views.decorators.csrf.csrf_view_exempt` decorators will
be removed. Since 1.4 ``csrf_response_exempt`` has been a no-op (it be removed. Since 1.4 ``csrf_response_exempt`` has been a no-op (it
returns the same function), and ``csrf_view_exempt`` has been a returns the same function), and ``csrf_view_exempt`` has been a
synonym for ``django.views.decorators.csrf.csrf_exempt``, which should synonym for ``django.views.decorators.csrf.csrf_exempt``, which should
be used to replace it. be used to replace it.
* The :class:`~django.core.cache.backends.memcached.CacheClass` backend * The :class:`~django.core.cache.backends.memcached.CacheClass` backend
was split into two in Django 1.3 in order to introduce support for was split into two in Django 1.3 in order to introduce support for
PyLibMC. The historical :class:`~django.core.cache.backends.memcached.CacheClass` PyLibMC. The historical :class:`~django.core.cache.backends.memcached.CacheClass`
will be removed in favor of :class:`~django.core.cache.backends.memcached.MemcachedCache`. will be removed in favor of :class:`~django.core.cache.backends.memcached.MemcachedCache`.
* The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only * The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only
be accessible through their GB-prefixed names (GB is the correct be accessible through their GB-prefixed names (GB is the correct
ISO 3166 code for United Kingdom). ISO 3166 code for United Kingdom).
* The :setting:`IGNORABLE_404_STARTS` and :setting:`IGNORABLE_404_ENDS` * The :setting:`IGNORABLE_404_STARTS` and :setting:`IGNORABLE_404_ENDS`
settings have been superseded by :setting:`IGNORABLE_404_URLS` in settings have been superseded by :setting:`IGNORABLE_404_URLS` in
the 1.4 release. They will be removed. the 1.4 release. They will be removed.
* The :doc:`form wizard </ref/contrib/formtools/form-wizard>` has been * The :doc:`form wizard </ref/contrib/formtools/form-wizard>` has been
refactored to use class based views with pluggable backends in 1.4. refactored to use class based views with pluggable backends in 1.4.
The previous implementation will be removed. The previous implementation will be removed.
* Legacy ways of calling * Legacy ways of calling
:func:`~django.views.decorators.cache.cache_page` will be removed. :func:`~django.views.decorators.cache.cache_page` will be removed.
* The backward-compatibility shim to automatically add a debug-false * The backward-compatibility shim to automatically add a debug-false
filter to the ``'mail_admins'`` logging handler will be removed. The filter to the ``'mail_admins'`` logging handler will be removed. The
:setting:`LOGGING` setting should include this filter explicitly if :setting:`LOGGING` setting should include this filter explicitly if
it is desired. it is desired.
* The template tag * The template tag
:func:`django.contrib.admin.templatetags.adminmedia.admin_media_prefix` :func:`django.contrib.admin.templatetags.adminmedia.admin_media_prefix`
will be removed in favor of the generic static files handling. will be removed in favor of the generic static files handling.
* The builtin truncation functions :func:`django.utils.text.truncate_words` * The builtin truncation functions :func:`django.utils.text.truncate_words`
and :func:`django.utils.text.truncate_html_words` will be removed in and :func:`django.utils.text.truncate_html_words` will be removed in
favor of the ``django.utils.text.Truncator`` class. favor of the ``django.utils.text.Truncator`` class.
* The :class:`~django.contrib.gis.geoip.GeoIP` class was moved to * The :class:`~django.contrib.gis.geoip.GeoIP` class was moved to
:mod:`django.contrib.gis.geoip` in 1.4 -- the shortcut in :mod:`django.contrib.gis.geoip` in 1.4 -- the shortcut in
:mod:`django.contrib.gis.utils` will be removed. :mod:`django.contrib.gis.utils` will be removed.
* ``django.conf.urls.defaults`` will be removed. The functions * ``django.conf.urls.defaults`` will be removed. The functions
:func:`~django.conf.urls.include`, :func:`~django.conf.urls.patterns` and :func:`~django.conf.urls.include`, :func:`~django.conf.urls.patterns` and
:func:`~django.conf.urls.url` plus :data:`~django.conf.urls.handler404`, :func:`~django.conf.urls.url` plus :data:`~django.conf.urls.handler404`,
:data:`~django.conf.urls.handler500`, are now available through :data:`~django.conf.urls.handler500`, are now available through
:mod:`django.conf.urls` . :mod:`django.conf.urls` .
* The Databrowse contrib module will be removed. * The Databrowse contrib module will be removed.
* The functions :func:`~django.core.management.setup_environ` and * The functions :func:`~django.core.management.setup_environ` and
:func:`~django.core.management.execute_manager` will be removed from :func:`~django.core.management.execute_manager` will be removed from
:mod:`django.core.management`. This also means that the old (pre-1.4) :mod:`django.core.management`. This also means that the old (pre-1.4)
style of :file:`manage.py` file will no longer work. style of :file:`manage.py` file will no longer work.
2.0 2.0
--- ---
* ``django.views.defaults.shortcut()``. This function has been moved * ``django.views.defaults.shortcut()``. This function has been moved
to ``django.contrib.contenttypes.views.shortcut()`` as part of the to ``django.contrib.contenttypes.views.shortcut()`` as part of the
goal of removing all ``django.contrib`` references from the core goal of removing all ``django.contrib`` references from the core
Django codebase. The old shortcut will be removed in the 2.0 Django codebase. The old shortcut will be removed in the 2.0
release. release.

View File

@ -9,27 +9,27 @@ Official releases
Since version 1.0, Django's release numbering works as follows: Since version 1.0, Django's release numbering works as follows:
* Versions are numbered in the form ``A.B`` or ``A.B.C``. * Versions are numbered in the form ``A.B`` or ``A.B.C``.
* ``A`` is the *major version* number, which is only incremented for major * ``A`` is the *major version* number, which is only incremented for major
changes to Django, and these changes are not necessarily changes to Django, and these changes are not necessarily
backwards-compatible. That is, code you wrote for Django 1.2 may break backwards-compatible. That is, code you wrote for Django 1.2 may break
when we release Django 2.0. when we release Django 2.0.
* ``B`` is the *minor version* number, which is incremented for large yet * ``B`` is the *minor version* number, which is incremented for large yet
backwards compatible changes. Code written for Django 1.2 will continue backwards compatible changes. Code written for Django 1.2 will continue
to work under Django 1.3. Exceptions to this rule will be listed in the to work under Django 1.3. Exceptions to this rule will be listed in the
release notes. release notes.
* ``C`` is the *micro version* number, which is incremented for bug and * ``C`` is the *micro version* number, which is incremented for bug and
security fixes. A new micro-release will be 100% backwards-compatible with security fixes. A new micro-release will be 100% backwards-compatible with
the previous micro-release. The only exception is when a security issue the previous micro-release. The only exception is when a security issue
can't be fixed without breaking backwards-compatibility. If this happens, can't be fixed without breaking backwards-compatibility. If this happens,
the release notes will provide detailed upgrade instructions. the release notes will provide detailed upgrade instructions.
* In some cases, we'll make alpha, beta, or release candidate releases. * In some cases, we'll make alpha, beta, or release candidate releases.
These are of the form ``A.B alpha/beta/rc N``, which means the ``Nth`` These are of the form ``A.B alpha/beta/rc N``, which means the ``Nth``
alpha/beta/release candidate of version ``A.B``. alpha/beta/release candidate of version ``A.B``.
In Subversion, each Django release will be tagged under ``tags/releases``. If In Subversion, each Django release will be tagged under ``tags/releases``. If
it's necessary to release a bug fix release or a security release that doesn't it's necessary to release a bug fix release or a security release that doesn't
@ -59,15 +59,15 @@ remove the feature entirely.
So, for example, if we decided to remove a function that existed in Django 1.0: So, for example, if we decided to remove a function that existed in Django 1.0:
* Django 1.1 will contain a backwards-compatible replica of the function * Django 1.1 will contain a backwards-compatible replica of the function
which will raise a ``PendingDeprecationWarning``. This warning is silent which will raise a ``PendingDeprecationWarning``. This warning is silent
by default; you need to explicitly turn on display of these warnings. by default; you need to explicitly turn on display of these warnings.
* Django 1.2 will contain the backwards-compatible replica, but the warning * Django 1.2 will contain the backwards-compatible replica, but the warning
will be promoted to a full-fledged ``DeprecationWarning``. This warning is will be promoted to a full-fledged ``DeprecationWarning``. This warning is
*loud* by default, and will likely be quite annoying. *loud* by default, and will likely be quite annoying.
* Django 1.3 will remove the feature outright. * Django 1.3 will remove the feature outright.
Micro releases Micro releases
-------------- --------------
@ -90,38 +90,38 @@ Supported versions
At any moment in time, Django's developer team will support a set of releases to At any moment in time, Django's developer team will support a set of releases to
varying levels: varying levels:
* The current development trunk will get new features and bug fixes * The current development trunk will get new features and bug fixes
requiring major refactoring. requiring major refactoring.
* Patches applied to the trunk will also be applied to the last minor * Patches applied to the trunk will also be applied to the last minor
release, to be released as the next micro release, when they fix critical release, to be released as the next micro release, when they fix critical
problems: problems:
* Security issues. * Security issues.
* Data-loss bugs. * Data-loss bugs.
* Crashing bugs. * Crashing bugs.
* Major functionality bugs in newly-introduced features. * Major functionality bugs in newly-introduced features.
The rule of thumb is that fixes will be backported to the last minor The rule of thumb is that fixes will be backported to the last minor
release for bugs that would have prevented a release in the first place. release for bugs that would have prevented a release in the first place.
* Security fixes will be applied to the current trunk and the previous two * Security fixes will be applied to the current trunk and the previous two
minor releases. minor releases.
As a concrete example, consider a moment in time halfway between the release of As a concrete example, consider a moment in time halfway between the release of
Django 1.3 and 1.4. At this point in time: Django 1.3 and 1.4. At this point in time:
* Features will be added to development trunk, to be released as Django 1.4. * Features will be added to development trunk, to be released as Django 1.4.
* Critical bug fixes will be applied to a ``1.3.X`` branch, and released as * Critical bug fixes will be applied to a ``1.3.X`` branch, and released as
1.3.1, 1.3.2, etc. 1.3.1, 1.3.2, etc.
* Security fixes will be applied to trunk, a ``1.3.X`` branch and a * Security fixes will be applied to trunk, a ``1.3.X`` branch and a
``1.2.X`` branch. They will trigger the release of ``1.3.1``, ``1.2.1``, ``1.2.X`` branch. They will trigger the release of ``1.3.1``, ``1.2.1``,
etc. etc.
.. _release-process: .. _release-process:
@ -204,15 +204,15 @@ Let's look at a hypothetical example for how this all first together. Imagine,
if you will, a point about halfway between 1.1 and 1.2. At this point, if you will, a point about halfway between 1.1 and 1.2. At this point,
development will be happening in a bunch of places: development will be happening in a bunch of places:
* On trunk, development towards 1.2 proceeds with small additions, bugs * On trunk, development towards 1.2 proceeds with small additions, bugs
fixes, etc. being checked in daily. fixes, etc. being checked in daily.
* On the branch "branches/releases/1.1.X", fixes for critical bugs found in * On the branch "branches/releases/1.1.X", fixes for critical bugs found in
the 1.1 release are checked in as needed. At some point, this branch will the 1.1 release are checked in as needed. At some point, this branch will
be released as "1.1.1", "1.1.2", etc. be released as "1.1.1", "1.1.2", etc.
* On the branch "branches/releases/1.0.X", security fixes are made if * On the branch "branches/releases/1.0.X", security fixes are made if
needed and released as "1.0.2", "1.0.3", etc. needed and released as "1.0.2", "1.0.3", etc.
* On feature branches, development of major features is done. These * On feature branches, development of major features is done. These
branches will be merged into trunk before the end of phase two. branches will be merged into trunk before the end of phase two.

View File

@ -57,17 +57,17 @@ Install Django
You've got three easy options to install Django: You've got three easy options to install Django:
* Install a version of Django :doc:`provided by your operating system * Install a version of Django :doc:`provided by your operating system
distribution </misc/distributions>`. This is the quickest option for those distribution </misc/distributions>`. This is the quickest option for those
who have operating systems that distribute Django. who have operating systems that distribute Django.
* :ref:`Install an official release <installing-official-release>`. This * :ref:`Install an official release <installing-official-release>`. This
is the best approach for users who want a stable version number and aren't is the best approach for users who want a stable version number and aren't
concerned about running a slightly older version of Django. concerned about running a slightly older version of Django.
* :ref:`Install the latest development version * :ref:`Install the latest development version
<installing-development-version>`. This is best for users who want the <installing-development-version>`. This is best for users who want the
latest-and-greatest features and aren't afraid of running brand-new code. latest-and-greatest features and aren't afraid of running brand-new code.
.. admonition:: Always refer to the documentation that corresponds to the .. admonition:: Always refer to the documentation that corresponds to the
version of Django you're using! version of Django you're using!

View File

@ -307,14 +307,14 @@ This is just the surface
This has been only a quick overview of Django's functionality. Some more useful This has been only a quick overview of Django's functionality. Some more useful
features: features:
* A :doc:`caching framework </topics/cache>` that integrates with memcached * A :doc:`caching framework </topics/cache>` that integrates with memcached
or other backends. or other backends.
* A :doc:`syndication framework </ref/contrib/syndication>` that makes * A :doc:`syndication framework </ref/contrib/syndication>` that makes
creating RSS and Atom feeds as easy as writing a small Python class. creating RSS and Atom feeds as easy as writing a small Python class.
* More sexy automatically-generated admin features -- this overview barely * More sexy automatically-generated admin features -- this overview barely
scratched the surface. scratched the surface.
The next obvious steps are for you to `download Django`_, read :doc:`the The next obvious steps are for you to `download Django`_, read :doc:`the
tutorial </intro/tutorial01>` and join `the community`_. Thanks for your tutorial </intro/tutorial01>` and join `the community`_. Thanks for your

View File

@ -9,8 +9,8 @@ poll application.
It'll consist of two parts: It'll consist of two parts:
* A public site that lets people view polls and vote in them. * A public site that lets people view polls and vote in them.
* An admin site that lets you add, change and delete polls. * An admin site that lets you add, change and delete polls.
We'll assume you have :doc:`Django installed </intro/install>` already. You can We'll assume you have :doc:`Django installed </intro/install>` already. You can
tell Django is installed by running the Python interactive interpreter and tell Django is installed by running the Python interactive interpreter and
@ -190,30 +190,30 @@ module-level variables representing Django settings. Change the
following keys in the :setting:`DATABASES` ``'default'`` item to match following keys in the :setting:`DATABASES` ``'default'`` item to match
your databases connection settings. your databases connection settings.
* :setting:`ENGINE <DATABASE-ENGINE>` -- Either * :setting:`ENGINE <DATABASE-ENGINE>` -- Either
``'django.db.backends.postgresql_psycopg2'``, ``'django.db.backends.postgresql_psycopg2'``,
``'django.db.backends.mysql'`` or ``'django.db.backends.mysql'`` or
``'django.db.backends.sqlite3'``. Other backends are ``'django.db.backends.sqlite3'``. Other backends are
:setting:`also available <DATABASE-ENGINE>`. :setting:`also available <DATABASE-ENGINE>`.
* :setting:`NAME` -- The name of your database. If you're using * :setting:`NAME` -- The name of your database. If you're using
SQLite, the database will be a file on your computer; in that SQLite, the database will be a file on your computer; in that
case, :setting:`NAME` should be the full absolute path, case, :setting:`NAME` should be the full absolute path,
including filename, of that file. If the file doesn't exist, it including filename, of that file. If the file doesn't exist, it
will automatically be created when you synchronize the database will automatically be created when you synchronize the database
for the first time (see below). for the first time (see below).
When specifying the path, always use forward slashes, even on When specifying the path, always use forward slashes, even on
Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``). Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
* :setting:`USER` -- Your database username (not used for SQLite). * :setting:`USER` -- Your database username (not used for SQLite).
* :setting:`PASSWORD` -- Your database password (not used for * :setting:`PASSWORD` -- Your database password (not used for
SQLite). SQLite).
* :setting:`HOST` -- The host your database is on. Leave this as * :setting:`HOST` -- The host your database is on. Leave this as
an empty string if your database server is on the same physical an empty string if your database server is on the same physical
machine (not used for SQLite). machine (not used for SQLite).
If you're new to databases, we recommend simply using SQLite (by If you're new to databases, we recommend simply using SQLite (by
setting :setting:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite setting :setting:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite
@ -238,19 +238,19 @@ distribute them for use by others in their projects.
By default, :setting:`INSTALLED_APPS` contains the following apps, all of which By default, :setting:`INSTALLED_APPS` contains the following apps, all of which
come with Django: come with Django:
* :mod:`django.contrib.auth` -- An authentication system. * :mod:`django.contrib.auth` -- An authentication system.
* :mod:`django.contrib.contenttypes` -- A framework for content types. * :mod:`django.contrib.contenttypes` -- A framework for content types.
* :mod:`django.contrib.sessions` -- A session framework. * :mod:`django.contrib.sessions` -- A session framework.
* :mod:`django.contrib.sites` -- A framework for managing multiple sites * :mod:`django.contrib.sites` -- A framework for managing multiple sites
with one Django installation. with one Django installation.
* :mod:`django.contrib.messages` -- A messaging framework. * :mod:`django.contrib.messages` -- A messaging framework.
* :mod:`django.contrib.staticfiles` -- A framework for managing * :mod:`django.contrib.staticfiles` -- A framework for managing
static files. static files.
These applications are included by default as a convenience for the common case. These applications are included by default as a convenience for the common case.
@ -390,8 +390,8 @@ Activating models
That small bit of model code gives Django a lot of information. With it, Django That small bit of model code gives Django a lot of information. With it, Django
is able to: is able to:
* Create a database schema (``CREATE TABLE`` statements) for this app. * Create a database schema (``CREATE TABLE`` statements) for this app.
* Create a Python database-access API for accessing Poll and Choice objects. * Create a Python database-access API for accessing Poll and Choice objects.
But first we need to tell our project that the ``polls`` app is installed. But first we need to tell our project that the ``polls`` app is installed.
@ -441,52 +441,52 @@ statements for the polls app):
Note the following: Note the following:
* The exact output will vary depending on the database you are using. * The exact output will vary depending on the database you are using.
* Table names are automatically generated by combining the name of the app * Table names are automatically generated by combining the name of the app
(``polls``) and the lowercase name of the model -- ``poll`` and (``polls``) and the lowercase name of the model -- ``poll`` and
``choice``. (You can override this behavior.) ``choice``. (You can override this behavior.)
* Primary keys (IDs) are added automatically. (You can override this, too.) * Primary keys (IDs) are added automatically. (You can override this, too.)
* By convention, Django appends ``"_id"`` to the foreign key field name. * By convention, Django appends ``"_id"`` to the foreign key field name.
Yes, you can override this, as well. Yes, you can override this, as well.
* The foreign key relationship is made explicit by a ``REFERENCES`` * The foreign key relationship is made explicit by a ``REFERENCES``
statement. statement.
* It's tailored to the database you're using, so database-specific field * It's tailored to the database you're using, so database-specific field
types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
``integer primary key`` (SQLite) are handled for you automatically. Same ``integer primary key`` (SQLite) are handled for you automatically. Same
goes for quoting of field names -- e.g., using double quotes or single goes for quoting of field names -- e.g., using double quotes or single
quotes. The author of this tutorial runs PostgreSQL, so the example quotes. The author of this tutorial runs PostgreSQL, so the example
output is in PostgreSQL syntax. output is in PostgreSQL syntax.
* The :djadmin:`sql` command doesn't actually run the SQL in your database - * The :djadmin:`sql` command doesn't actually run the SQL in your database -
it just prints it to the screen so that you can see what SQL Django thinks it just prints it to the screen so that you can see what SQL Django thinks
is required. If you wanted to, you could copy and paste this SQL into your is required. If you wanted to, you could copy and paste this SQL into your
database prompt. However, as we will see shortly, Django provides an database prompt. However, as we will see shortly, Django provides an
easier way of committing the SQL to the database. easier way of committing the SQL to the database.
If you're interested, also run the following commands: If you're interested, also run the following commands:
* :djadmin:`python manage.py validate <validate>` -- Checks for any errors * :djadmin:`python manage.py validate <validate>` -- Checks for any errors
in the construction of your models. in the construction of your models.
* :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any * :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any
:ref:`custom SQL statements <initial-sql>` (such as table modifications or :ref:`custom SQL statements <initial-sql>` (such as table modifications or
constraints) that are defined for the application. constraints) that are defined for the application.
* :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the * :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the
necessary ``DROP TABLE`` statements for this app, according to which necessary ``DROP TABLE`` statements for this app, according to which
tables already exist in your database (if any). tables already exist in your database (if any).
* :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the * :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the
``CREATE INDEX`` statements for this app. ``CREATE INDEX`` statements for this app.
* :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all * :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all
the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and
:djadmin:`sqlindexes` commands. :djadmin:`sqlindexes` commands.
Looking at the output of those commands can help you understand what's actually Looking at the output of those commands can help you understand what's actually
happening under the hood. happening under the hood.

View File

@ -27,38 +27,38 @@ Activate the admin site
The Django admin site is not activated by default -- it's an opt-in thing. To The Django admin site is not activated by default -- it's an opt-in thing. To
activate the admin site for your installation, do these three things: activate the admin site for your installation, do these three things:
* Add ``"django.contrib.admin"`` to your :setting:`INSTALLED_APPS` setting. * Add ``"django.contrib.admin"`` to your :setting:`INSTALLED_APPS` setting.
* Run ``python manage.py syncdb``. Since you have added a new application * Run ``python manage.py syncdb``. Since you have added a new application
to :setting:`INSTALLED_APPS`, the database tables need to be updated. to :setting:`INSTALLED_APPS`, the database tables need to be updated.
* Edit your ``mysite/urls.py`` file and uncomment the lines that reference * Edit your ``mysite/urls.py`` file and uncomment the lines that reference
the admin -- there are three lines in total to uncomment. This file is a the admin -- there are three lines in total to uncomment. This file is a
URLconf; we'll dig into URLconfs in the next tutorial. For now, all you URLconf; we'll dig into URLconfs in the next tutorial. For now, all you
need to know is that it maps URL roots to applications. In the end, you need to know is that it maps URL roots to applications. In the end, you
should have a ``urls.py`` file that looks like this: should have a ``urls.py`` file that looks like this:
.. parsed-literal:: .. parsed-literal::
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin: # Uncomment the next two lines to enable the admin:
**from django.contrib import admin** **from django.contrib import admin**
**admin.autodiscover()** **admin.autodiscover()**
urlpatterns = patterns('', urlpatterns = patterns('',
# Examples: # Examples:
# url(r'^$', '{{ project_name }}.views.home', name='home'), # url(r'^$', '{{ project_name }}.views.home', name='home'),
# url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')), # url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation: # Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin: # Uncomment the next line to enable the admin:
**url(r'^admin/', include(admin.site.urls)),** **url(r'^admin/', include(admin.site.urls)),**
) )
(The bold lines are the ones that needed to be uncommented.) (The bold lines are the ones that needed to be uncommented.)
Start the development server Start the development server
============================ ============================
@ -145,29 +145,29 @@ Click the "What's up?" poll to edit it:
Things to note here: Things to note here:
* The form is automatically generated from the Poll model. * The form is automatically generated from the Poll model.
* The different model field types (:class:`~django.db.models.DateTimeField`, * The different model field types (:class:`~django.db.models.DateTimeField`,
:class:`~django.db.models.CharField`) correspond to the appropriate HTML :class:`~django.db.models.CharField`) correspond to the appropriate HTML
input widget. Each type of field knows how to display itself in the Django input widget. Each type of field knows how to display itself in the Django
admin. admin.
* Each :class:`~django.db.models.DateTimeField` gets free JavaScript * Each :class:`~django.db.models.DateTimeField` gets free JavaScript
shortcuts. Dates get a "Today" shortcut and calendar popup, and times get shortcuts. Dates get a "Today" shortcut and calendar popup, and times get
a "Now" shortcut and a convenient popup that lists commonly entered times. a "Now" shortcut and a convenient popup that lists commonly entered times.
The bottom part of the page gives you a couple of options: The bottom part of the page gives you a couple of options:
* Save -- Saves changes and returns to the change-list page for this type of * Save -- Saves changes and returns to the change-list page for this type of
object. object.
* Save and continue editing -- Saves changes and reloads the admin page for * Save and continue editing -- Saves changes and reloads the admin page for
this object. this object.
* Save and add another -- Saves changes and loads a new, blank form for this * Save and add another -- Saves changes and loads a new, blank form for this
type of object. type of object.
* Delete -- Displays a delete confirmation page. * Delete -- Displays a delete confirmation page.
Change the "Date published" by clicking the "Today" and "Now" shortcuts. Then Change the "Date published" by clicking the "Today" and "Now" shortcuts. Then
click "Save and continue editing." Then click "History" in the upper right. click "Save and continue editing." Then click "History" in the upper right.

View File

@ -13,31 +13,31 @@ A view is a "type" of Web page in your Django application that generally serves
a specific function and has a specific template. For example, in a Weblog a specific function and has a specific template. For example, in a Weblog
application, you might have the following views: application, you might have the following views:
* Blog homepage -- displays the latest few entries. * Blog homepage -- displays the latest few entries.
* Entry "detail" page -- permalink page for a single entry. * Entry "detail" page -- permalink page for a single entry.
* Year-based archive page -- displays all months with entries in the * Year-based archive page -- displays all months with entries in the
given year. given year.
* Month-based archive page -- displays all days with entries in the * Month-based archive page -- displays all days with entries in the
given month. given month.
* Day-based archive page -- displays all entries in the given day. * Day-based archive page -- displays all entries in the given day.
* Comment action -- handles posting comments to a given entry. * Comment action -- handles posting comments to a given entry.
In our poll application, we'll have the following four views: In our poll application, we'll have the following four views:
* Poll "index" page -- displays the latest few polls. * Poll "index" page -- displays the latest few polls.
* Poll "detail" page -- displays a poll question, with no results but * Poll "detail" page -- displays a poll question, with no results but
with a form to vote. with a form to vote.
* Poll "results" page -- displays results for a particular poll. * Poll "results" page -- displays results for a particular poll.
* Vote action -- handles voting for a particular choice in a particular * Vote action -- handles voting for a particular choice in a particular
poll. poll.
In Django, each view is represented by a simple Python function. In Django, each view is represented by a simple Python function.
@ -375,21 +375,21 @@ in ``django/conf/urls/defaults.py``, ``handler404`` is set to
Four more things to note about 404 views: Four more things to note about 404 views:
* If :setting:`DEBUG` is set to ``True`` (in your settings module) then your * If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
404 view will never be used (and thus the ``404.html`` template will never 404 view will never be used (and thus the ``404.html`` template will never
be rendered) because the traceback will be displayed instead. be rendered) because the traceback will be displayed instead.
* The 404 view is also called if Django doesn't find a match after checking * The 404 view is also called if Django doesn't find a match after checking
every regular expression in the URLconf. every regular expression in the URLconf.
* If you don't define your own 404 view -- and simply use the default, which * If you don't define your own 404 view -- and simply use the default, which
is recommended -- you still have one obligation: To create a ``404.html`` is recommended -- you still have one obligation: To create a ``404.html``
template in the root of your template directory. The default 404 view will template in the root of your template directory. The default 404 view will
use that template for all 404 errors. use that template for all 404 errors.
* If :setting:`DEBUG` is set to ``False`` (in your settings module) and if * If :setting:`DEBUG` is set to ``False`` (in your settings module) and if
you didn't create a ``404.html`` file, an ``Http500`` is raised instead. you didn't create a ``404.html`` file, an ``Http500`` is raised instead.
So remember to create a ``404.html``. So remember to create a ``404.html``.
Write a 500 (server error) view Write a 500 (server error) view
=============================== ===============================
@ -517,11 +517,11 @@ URLconf for further processing.
Here's what happens if a user goes to "/polls/34/" in this system: Here's what happens if a user goes to "/polls/34/" in this system:
* Django will find the match at ``'^polls/'`` * Django will find the match at ``'^polls/'``
* Then, Django will strip off the matching text (``"polls/"``) and send the * Then, Django will strip off the matching text (``"polls/"``) and send the
remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
further processing. further processing.
Now that we've decoupled that, we need to decouple the ``polls.urls`` Now that we've decoupled that, we need to decouple the ``polls.urls``
URLconf by removing the leading "polls/" from each line, and removing the URLconf by removing the leading "polls/" from each line, and removing the

View File

@ -29,28 +29,28 @@ tutorial, so that the template contains an HTML ``<form>`` element:
A quick rundown: A quick rundown:
* The above template displays a radio button for each poll choice. The * The above template displays a radio button for each poll choice. The
``value`` of each radio button is the associated poll choice's ID. The ``value`` of each radio button is the associated poll choice's ID. The
``name`` of each radio button is ``"choice"``. That means, when somebody ``name`` of each radio button is ``"choice"``. That means, when somebody
selects one of the radio buttons and submits the form, it'll send the selects one of the radio buttons and submits the form, it'll send the
POST data ``choice=3``. This is HTML Forms 101. POST data ``choice=3``. This is HTML Forms 101.
* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we * We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
set ``method="post"``. Using ``method="post"`` (as opposed to set ``method="post"``. Using ``method="post"`` (as opposed to
``method="get"``) is very important, because the act of submitting this ``method="get"``) is very important, because the act of submitting this
form will alter data server-side. Whenever you create a form that alters form will alter data server-side. Whenever you create a form that alters
data server-side, use ``method="post"``. This tip isn't specific to data server-side, use ``method="post"``. This tip isn't specific to
Django; it's just good Web development practice. Django; it's just good Web development practice.
* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone * ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
through its loop through its loop
* Since we're creating a POST form (which can have the effect of modifying * Since we're creating a POST form (which can have the effect of modifying
data), we need to worry about Cross Site Request Forgeries. data), we need to worry about Cross Site Request Forgeries.
Thankfully, you don't have to worry too hard, because Django comes with Thankfully, you don't have to worry too hard, because Django comes with
a very easy-to-use system for protecting against it. In short, all POST a very easy-to-use system for protecting against it. In short, all POST
forms that are targeted at internal URLs should use the forms that are targeted at internal URLs should use the
:ttag:`{% csrf_token %}<csrf_token>` template tag. :ttag:`{% csrf_token %}<csrf_token>` template tag.
The :ttag:`{% csrf_token %}<csrf_token>` tag requires information from the The :ttag:`{% csrf_token %}<csrf_token>` tag requires information from the
request object, which is not normally accessible from within the template request object, which is not normally accessible from within the template
@ -102,48 +102,48 @@ create a real version. Add the following to ``polls/views.py``::
This code includes a few things we haven't covered yet in this tutorial: This code includes a few things we haven't covered yet in this tutorial:
* :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like * :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like
object that lets you access submitted data by key name. In this case, object that lets you access submitted data by key name. In this case,
``request.POST['choice']`` returns the ID of the selected choice, as a ``request.POST['choice']`` returns the ID of the selected choice, as a
string. :attr:`request.POST <django.http.HttpRequest.POST>` values are string. :attr:`request.POST <django.http.HttpRequest.POST>` values are
always strings. always strings.
Note that Django also provides :attr:`request.GET Note that Django also provides :attr:`request.GET
<django.http.HttpRequest.GET>` for accessing GET data in the same way -- <django.http.HttpRequest.GET>` for accessing GET data in the same way --
but we're explicitly using :attr:`request.POST but we're explicitly using :attr:`request.POST
<django.http.HttpRequest.POST>` in our code, to ensure that data is only <django.http.HttpRequest.POST>` in our code, to ensure that data is only
altered via a POST call. altered via a POST call.
* ``request.POST['choice']`` will raise :exc:`KeyError` if ``choice`` wasn't * ``request.POST['choice']`` will raise :exc:`KeyError` if ``choice`` wasn't
provided in POST data. The above code checks for :exc:`KeyError` and provided in POST data. The above code checks for :exc:`KeyError` and
redisplays the poll form with an error message if ``choice`` isn't given. redisplays the poll form with an error message if ``choice`` isn't given.
* After incrementing the choice count, the code returns an * After incrementing the choice count, the code returns an
:class:`~django.http.HttpResponseRedirect` rather than a normal :class:`~django.http.HttpResponseRedirect` rather than a normal
:class:`~django.http.HttpResponse`. :class:`~django.http.HttpResponse`.
:class:`~django.http.HttpResponseRedirect` takes a single argument: the :class:`~django.http.HttpResponseRedirect` takes a single argument: the
URL to which the user will be redirected (see the following point for how URL to which the user will be redirected (see the following point for how
we construct the URL in this case). we construct the URL in this case).
As the Python comment above points out, you should always return an As the Python comment above points out, you should always return an
:class:`~django.http.HttpResponseRedirect` after successfully dealing with :class:`~django.http.HttpResponseRedirect` after successfully dealing with
POST data. This tip isn't specific to Django; it's just good Web POST data. This tip isn't specific to Django; it's just good Web
development practice. development practice.
* We are using the :func:`~django.core.urlresolvers.reverse` function in the * We are using the :func:`~django.core.urlresolvers.reverse` function in the
:class:`~django.http.HttpResponseRedirect` constructor in this example. :class:`~django.http.HttpResponseRedirect` constructor in this example.
This function helps avoid having to hardcode a URL in the view function. This function helps avoid having to hardcode a URL in the view function.
It is given the name of the view that we want to pass control to and the It is given the name of the view that we want to pass control to and the
variable portion of the URL pattern that points to that view. In this variable portion of the URL pattern that points to that view. In this
case, using the URLconf we set up in Tutorial 3, this case, using the URLconf we set up in Tutorial 3, this
:func:`~django.core.urlresolvers.reverse` call will return a string like :func:`~django.core.urlresolvers.reverse` call will return a string like
:: ::
'/polls/3/results/' '/polls/3/results/'
... where the ``3`` is the value of ``p.id``. This redirected URL will ... where the ``3`` is the value of ``p.id``. This redirected URL will
then call the ``'results'`` view to display the final page. Note that you then call the ``'results'`` view to display the final page. Note that you
need to use the full name of the view here (including the prefix). need to use the full name of the view here (including the prefix).
As mentioned in Tutorial 3, ``request`` is a :class:`~django.http.HttpRequest` As mentioned in Tutorial 3, ``request`` is a :class:`~django.http.HttpRequest`
object. For more on :class:`~django.http.HttpRequest` objects, see the object. For more on :class:`~django.http.HttpRequest` objects, see the
@ -197,11 +197,11 @@ Let's convert our poll app to use the generic views system, so we can delete a
bunch of our own code. We'll just have to take a few steps to make the bunch of our own code. We'll just have to take a few steps to make the
conversion. We will: conversion. We will:
1. Convert the URLconf. 1. Convert the URLconf.
2. Delete some of the old, unneeded views. 2. Delete some of the old, unneeded views.
3. Fix up URL handling for the new views. 3. Fix up URL handling for the new views.
Read on for details. Read on for details.
@ -257,22 +257,22 @@ We're using two generic views here:
two views abstract the concepts of "display a list of objects" and two views abstract the concepts of "display a list of objects" and
"display a detail page for a particular type of object." "display a detail page for a particular type of object."
* Each generic view needs to know what model it will be acting * Each generic view needs to know what model it will be acting
upon. This is provided using the ``model`` parameter. upon. This is provided using the ``model`` parameter.
* The :class:`~django.views.generic.list.DetailView` generic view * The :class:`~django.views.generic.list.DetailView` generic view
expects the primary key value captured from the URL to be called expects the primary key value captured from the URL to be called
``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic ``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic
views. views.
* We've added a name, ``poll_results``, to the results view so * We've added a name, ``poll_results``, to the results view so
that we have a way to refer to its URL later on (see the that we have a way to refer to its URL later on (see the
documentation about :ref:`naming URL patterns documentation about :ref:`naming URL patterns
<naming-url-patterns>` for information). We're also using the <naming-url-patterns>` for information). We're also using the
:func:`~django.conf.urls.url` function from :func:`~django.conf.urls.url` function from
:mod:`django.conf.urls` here. It's a good habit to use :mod:`django.conf.urls` here. It's a good habit to use
:func:`~django.conf.urls.url` when you are providing a :func:`~django.conf.urls.url` when you are providing a
pattern name like this. pattern name like this.
By default, the :class:`~django.views.generic.list.DetailView` generic By default, the :class:`~django.views.generic.list.DetailView` generic
view uses a template called ``<app name>/<model name>_detail.html``. view uses a template called ``<app name>/<model name>_detail.html``.
@ -328,12 +328,12 @@ Coming soon
The tutorial ends here for the time being. Future installments of the tutorial The tutorial ends here for the time being. Future installments of the tutorial
will cover: will cover:
* Advanced form processing * Advanced form processing
* Using the RSS framework * Using the RSS framework
* Using the cache framework * Using the cache framework
* Using the comments framework * Using the comments framework
* Advanced admin features: Permissions * Advanced admin features: Permissions
* Advanced admin features: Custom JavaScript * Advanced admin features: Custom JavaScript
In the meantime, you might want to check out some pointers on :doc:`where to go In the meantime, you might want to check out some pointers on :doc:`where to go
from here </intro/whatsnext>` from here </intro/whatsnext>`

View File

@ -35,43 +35,43 @@ How the documentation is organized
Django's main documentation is broken up into "chunks" designed to fill Django's main documentation is broken up into "chunks" designed to fill
different needs: different needs:
* The :doc:`introductory material </intro/index>` is designed for people new * The :doc:`introductory material </intro/index>` is designed for people new
to Django -- or to Web development in general. It doesn't cover anything to Django -- or to Web development in general. It doesn't cover anything
in depth, but instead gives a high-level overview of how developing in in depth, but instead gives a high-level overview of how developing in
Django "feels". Django "feels".
* The :doc:`topic guides </topics/index>`, on the other hand, dive deep into * The :doc:`topic guides </topics/index>`, on the other hand, dive deep into
individual parts of Django. There are complete guides to Django's individual parts of Django. There are complete guides to Django's
:doc:`model system </topics/db/index>`, :doc:`template engine :doc:`model system </topics/db/index>`, :doc:`template engine
</topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much </topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much
more. more.
This is probably where you'll want to spend most of your time; if you work This is probably where you'll want to spend most of your time; if you work
your way through these guides you should come out knowing pretty much your way through these guides you should come out knowing pretty much
everything there is to know about Django. everything there is to know about Django.
* Web development is often broad, not deep -- problems span many domains. * Web development is often broad, not deep -- problems span many domains.
We've written a set of :doc:`how-to guides </howto/index>` that answer We've written a set of :doc:`how-to guides </howto/index>` that answer
common "How do I ...?" questions. Here you'll find information about common "How do I ...?" questions. Here you'll find information about
:doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing :doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing
custom template tags </howto/custom-template-tags>`, and more. custom template tags </howto/custom-template-tags>`, and more.
Answers to really common questions can also be found in the :doc:`FAQ Answers to really common questions can also be found in the :doc:`FAQ
</faq/index>`. </faq/index>`.
* The guides and how-to's don't cover every single class, function, and * The guides and how-to's don't cover every single class, function, and
method available in Django -- that would be overwhelming when you're method available in Django -- that would be overwhelming when you're
trying to learn. Instead, details about individual classes, functions, trying to learn. Instead, details about individual classes, functions,
methods, and modules are kept in the :doc:`reference </ref/index>`. This is methods, and modules are kept in the :doc:`reference </ref/index>`. This is
where you'll turn to find the details of a particular function or where you'll turn to find the details of a particular function or
whathaveyou. whathaveyou.
* Finally, there's some "specialized" documentation not usually relevant to * Finally, there's some "specialized" documentation not usually relevant to
most developers. This includes the :doc:`release notes </releases/index>`, most developers. This includes the :doc:`release notes </releases/index>`,
:doc:`documentation of obsolete features </obsolete/index>`, :doc:`documentation of obsolete features </obsolete/index>`,
:doc:`internals documentation </internals/index>` for those who want to add :doc:`internals documentation </internals/index>` for those who want to add
code to Django itself, and a :doc:`few other things that simply don't fit code to Django itself, and a :doc:`few other things that simply don't fit
elsewhere </misc/index>`. elsewhere </misc/index>`.
How documentation is updated How documentation is updated
@ -81,16 +81,16 @@ Just as the Django code base is developed and improved on a daily basis, our
documentation is consistently improving. We improve documentation for several documentation is consistently improving. We improve documentation for several
reasons: reasons:
* To make content fixes, such as grammar/typo corrections. * To make content fixes, such as grammar/typo corrections.
* To add information and/or examples to existing sections that need to be * To add information and/or examples to existing sections that need to be
expanded. expanded.
* To document Django features that aren't yet documented. (The list of * To document Django features that aren't yet documented. (The list of
such features is shrinking but exists nonetheless.) such features is shrinking but exists nonetheless.)
* To add documentation for new features as new features get added, or as * To add documentation for new features as new features get added, or as
Django APIs or behaviors change. Django APIs or behaviors change.
Django's documentation is kept in the same source control system as its code. It Django's documentation is kept in the same source control system as its code. It
lives in the `django/trunk/docs`_ directory of our Subversion repository. Each lives in the `django/trunk/docs`_ directory of our Subversion repository. Each
@ -164,33 +164,33 @@ As HTML, locally
You can get a local copy of the HTML documentation following a few easy steps: You can get a local copy of the HTML documentation following a few easy steps:
* Django's documentation uses a system called Sphinx__ to convert from * Django's documentation uses a system called Sphinx__ to convert from
plain text to HTML. You'll need to install Sphinx by either downloading plain text to HTML. You'll need to install Sphinx by either downloading
and installing the package from the Sphinx Web site, or by Python's and installing the package from the Sphinx Web site, or by Python's
``easy_install``: ``easy_install``:
.. code-block:: bash .. code-block:: bash
$ easy_install Sphinx $ easy_install Sphinx
* Then, just use the included ``Makefile`` to turn the documentation into * Then, just use the included ``Makefile`` to turn the documentation into
HTML: HTML:
.. code-block:: bash .. code-block:: bash
$ cd path/to/django/docs $ cd path/to/django/docs
$ make html $ make html
You'll need `GNU Make`__ installed for this. You'll need `GNU Make`__ installed for this.
If you're on Windows you can alternatively use the included batch file: If you're on Windows you can alternatively use the included batch file:
.. code-block:: bat .. code-block:: bat
cd path\to\django\docs cd path\to\django\docs
make.bat html make.bat html
* The HTML documentation will be placed in ``docs/_build/html``. * The HTML documentation will be placed in ``docs/_build/html``.
.. note:: .. note::
@ -212,27 +212,27 @@ versions of the framework.
We follow this policy: We follow this policy:
* The primary documentation on djangoproject.com is an HTML version of the * The primary documentation on djangoproject.com is an HTML version of the
latest docs in Subversion. These docs always correspond to the latest latest docs in Subversion. These docs always correspond to the latest
official Django release, plus whatever features we've added/changed in official Django release, plus whatever features we've added/changed in
the framework *since* the latest release. the framework *since* the latest release.
* As we add features to Django's development version, we try to update the * As we add features to Django's development version, we try to update the
documentation in the same Subversion commit transaction. documentation in the same Subversion commit transaction.
* To distinguish feature changes/additions in the docs, we use the phrase: * To distinguish feature changes/additions in the docs, we use the phrase:
"New in version X.Y", being X.Y the next release version (hence, the one "New in version X.Y", being X.Y the next release version (hence, the one
being developed). being developed).
* Documentation for a particular Django release is frozen once the version * Documentation for a particular Django release is frozen once the version
has been released officially. It remains a snapshot of the docs as of the has been released officially. It remains a snapshot of the docs as of the
moment of the release. We will make exceptions to this rule in moment of the release. We will make exceptions to this rule in
the case of retroactive security updates or other such retroactive the case of retroactive security updates or other such retroactive
changes. Once documentation is frozen, we add a note to the top of each changes. Once documentation is frozen, we add a note to the top of each
frozen document that says "These docs are frozen for Django version XXX" frozen document that says "These docs are frozen for Django version XXX"
and links to the current version of that document. and links to the current version of that document.
* The `main documentation Web page`_ includes links to documentation for * The `main documentation Web page`_ includes links to documentation for
all previous versions. all previous versions.
.. _main documentation Web page: http://docs.djangoproject.com/en/dev/ .. _main documentation Web page: http://docs.djangoproject.com/en/dev/

View File

@ -12,24 +12,24 @@ What "stable" means
In this context, stable means: In this context, stable means:
- All the public APIs -- everything documented in the linked documents below, - All the public APIs -- everything documented in the linked documents below,
and all methods that don't begin with an underscore -- will not be moved or and all methods that don't begin with an underscore -- will not be moved or
renamed without providing backwards-compatible aliases. renamed without providing backwards-compatible aliases.
- If new features are added to these APIs -- which is quite possible -- - If new features are added to these APIs -- which is quite possible --
they will not break or change the meaning of existing methods. In other they will not break or change the meaning of existing methods. In other
words, "stable" does not (necessarily) mean "complete." words, "stable" does not (necessarily) mean "complete."
- If, for some reason, an API declared stable must be removed or replaced, it - If, for some reason, an API declared stable must be removed or replaced, it
will be declared deprecated but will remain in the API for at least two will be declared deprecated but will remain in the API for at least two
minor version releases. Warnings will be issued when the deprecated method minor version releases. Warnings will be issued when the deprecated method
is called. is called.
See :ref:`official-releases` for more details on how Django's version See :ref:`official-releases` for more details on how Django's version
numbering scheme works, and how features will be deprecated. numbering scheme works, and how features will be deprecated.
- We'll only break backwards compatibility of these APIs if a bug or - We'll only break backwards compatibility of these APIs if a bug or
security hole makes it completely unavoidable. security hole makes it completely unavoidable.
Stable APIs Stable APIs
=========== ===========
@ -38,58 +38,58 @@ In general, everything covered in the documentation -- with the exception of
anything in the :doc:`internals area </internals/index>` is considered stable as anything in the :doc:`internals area </internals/index>` is considered stable as
of 1.0. This includes these APIs: of 1.0. This includes these APIs:
- :doc:`Authorization </topics/auth>` - :doc:`Authorization </topics/auth>`
- :doc:`Caching </topics/cache>`. - :doc:`Caching </topics/cache>`.
- :doc:`Model definition, managers, querying and transactions - :doc:`Model definition, managers, querying and transactions
</topics/db/index>` </topics/db/index>`
- :doc:`Sending email </topics/email>`. - :doc:`Sending email </topics/email>`.
- :doc:`File handling and storage </topics/files>` - :doc:`File handling and storage </topics/files>`
- :doc:`Forms </topics/forms/index>` - :doc:`Forms </topics/forms/index>`
- :doc:`HTTP request/response handling </topics/http/index>`, including file - :doc:`HTTP request/response handling </topics/http/index>`, including file
uploads, middleware, sessions, URL resolution, view, and shortcut APIs. uploads, middleware, sessions, URL resolution, view, and shortcut APIs.
- :doc:`Generic views </topics/http/generic-views>`. - :doc:`Generic views </topics/http/generic-views>`.
- :doc:`Internationalization </topics/i18n/index>`. - :doc:`Internationalization </topics/i18n/index>`.
- :doc:`Pagination </topics/pagination>` - :doc:`Pagination </topics/pagination>`
- :doc:`Serialization </topics/serialization>` - :doc:`Serialization </topics/serialization>`
- :doc:`Signals </topics/signals>` - :doc:`Signals </topics/signals>`
- :doc:`Templates </topics/templates>`, including the language, Python-level - :doc:`Templates </topics/templates>`, including the language, Python-level
:doc:`template APIs </ref/templates/index>`, and :doc:`custom template tags :doc:`template APIs </ref/templates/index>`, and :doc:`custom template tags
and libraries </howto/custom-template-tags>`. We may add new template and libraries </howto/custom-template-tags>`. We may add new template
tags in the future and the names may inadvertently clash with tags in the future and the names may inadvertently clash with
external template tags. Before adding any such tags, we'll ensure that external template tags. Before adding any such tags, we'll ensure that
Django raises an error if it tries to load tags with duplicate names. Django raises an error if it tries to load tags with duplicate names.
- :doc:`Testing </topics/testing>` - :doc:`Testing </topics/testing>`
- :doc:`django-admin utility </ref/django-admin>`. - :doc:`django-admin utility </ref/django-admin>`.
- :doc:`Built-in middleware </ref/middleware>` - :doc:`Built-in middleware </ref/middleware>`
- :doc:`Request/response objects </ref/request-response>`. - :doc:`Request/response objects </ref/request-response>`.
- :doc:`Settings </ref/settings>`. Note, though that while the :doc:`list of - :doc:`Settings </ref/settings>`. Note, though that while the :doc:`list of
built-in settings </ref/settings>` can be considered complete we may -- and built-in settings </ref/settings>` can be considered complete we may -- and
probably will -- add new settings in future versions. This is one of those probably will -- add new settings in future versions. This is one of those
places where "'stable' does not mean 'complete.'" places where "'stable' does not mean 'complete.'"
- :doc:`Built-in signals </ref/signals>`. Like settings, we'll probably add - :doc:`Built-in signals </ref/signals>`. Like settings, we'll probably add
new signals in the future, but the existing ones won't break. new signals in the future, but the existing ones won't break.
- :doc:`Unicode handling </ref/unicode>`. - :doc:`Unicode handling </ref/unicode>`.
- Everything covered by the :doc:`HOWTO guides </howto/index>`. - Everything covered by the :doc:`HOWTO guides </howto/index>`.
``django.utils`` ``django.utils``
---------------- ----------------
@ -97,15 +97,15 @@ of 1.0. This includes these APIs:
Most of the modules in ``django.utils`` are designed for internal use. Only Most of the modules in ``django.utils`` are designed for internal use. Only
the following parts of :doc:`django.utils </ref/utils>` can be considered stable: the following parts of :doc:`django.utils </ref/utils>` can be considered stable:
- ``django.utils.cache`` - ``django.utils.cache``
- ``django.utils.datastructures.SortedDict`` -- only this single class; the - ``django.utils.datastructures.SortedDict`` -- only this single class; the
rest of the module is for internal use. rest of the module is for internal use.
- ``django.utils.encoding`` - ``django.utils.encoding``
- ``django.utils.feedgenerator`` - ``django.utils.feedgenerator``
- ``django.utils.http`` - ``django.utils.http``
- ``django.utils.safestring`` - ``django.utils.safestring``
- ``django.utils.translation`` - ``django.utils.translation``
- ``django.utils.tzinfo`` - ``django.utils.tzinfo``
Exceptions Exceptions
========== ==========
@ -142,13 +142,13 @@ APIs marked as internal
Certain APIs are explicitly marked as "internal" in a couple of ways: Certain APIs are explicitly marked as "internal" in a couple of ways:
- Some documentation refers to internals and mentions them as such. If the - Some documentation refers to internals and mentions them as such. If the
documentation says that something is internal, we reserve the right to documentation says that something is internal, we reserve the right to
change it. change it.
- Functions, methods, and other objects prefixed by a leading underscore - Functions, methods, and other objects prefixed by a leading underscore
(``_``). This is the standard Python way of indicating that something is (``_``). This is the standard Python way of indicating that something is
private; if any method starts with a single ``_``, it's an internal API. private; if any method starts with a single ``_``, it's an internal API.
.. _misc-api-stability-localflavor: .. _misc-api-stability-localflavor:
@ -174,29 +174,29 @@ database -- including values that may no longer be valid.
Therefore, Django has the following policy with respect to changes in Therefore, Django has the following policy with respect to changes in
local flavor: local flavor:
* At the time of a Django release, the data and algorithms * At the time of a Django release, the data and algorithms
contained in :mod:`django.contrib.localflavor` will, to the best contained in :mod:`django.contrib.localflavor` will, to the best
of our ability, reflect the officially gazetted policies of the of our ability, reflect the officially gazetted policies of the
appropriate local government authority. If a province has been appropriate local government authority. If a province has been
added, altered, or removed, that change will be reflected in added, altered, or removed, that change will be reflected in
Django's localflavor. Django's localflavor.
* These changes will *not* be backported to the previous stable * These changes will *not* be backported to the previous stable
release. Upgrading a minor version of Django should not require release. Upgrading a minor version of Django should not require
any data migration or audits for UI changes; therefore, if you any data migration or audits for UI changes; therefore, if you
want to get the latest province list, you will either need to want to get the latest province list, you will either need to
upgrade your Django install, or backport the province list you upgrade your Django install, or backport the province list you
need. need.
* For one release, the affected localflavor module will raise a * For one release, the affected localflavor module will raise a
``RuntimeWarning`` when it is imported. ``RuntimeWarning`` when it is imported.
* The change will be announced in the release notes as a backwards * The change will be announced in the release notes as a backwards
incompatible change requiring attention. The change will also be incompatible change requiring attention. The change will also be
annotated in the documentation for the localflavor module. annotated in the documentation for the localflavor module.
* Where necessary and feasible, a migration script will be provided * Where necessary and feasible, a migration script will be provided
to aid the migration process. to aid the migration process.
For example, Django 1.2 contains an Indonesian localflavor. It has a For example, Django 1.2 contains an Indonesian localflavor. It has a
province list that includes "Nanggroe Aceh Darussalam (NAD)" as a province list that includes "Nanggroe Aceh Darussalam (NAD)" as a

View File

@ -254,8 +254,8 @@ Don't invent a programming language
The template system intentionally doesn't allow the following: The template system intentionally doesn't allow the following:
* Assignment to variables * Assignment to variables
* Advanced logic * Advanced logic
The goal is not to invent a programming language. The goal is to offer just The goal is not to invent a programming language. The goal is to offer just
enough programming-esque functionality, such as branching and looping, that is enough programming-esque functionality, such as branching and looping, that is

View File

@ -41,13 +41,13 @@ usable generic views.
For example, the :class:`~django.views.generic.base.detail.DetailView` For example, the :class:`~django.views.generic.base.detail.DetailView`
is composed from: is composed from:
* :class:`~django.db.views.generic.base.View`, which provides the * :class:`~django.db.views.generic.base.View`, which provides the
basic class-based behavior basic class-based behavior
* :class:`~django.db.views.generic.detail.SingleObjectMixin`, which * :class:`~django.db.views.generic.detail.SingleObjectMixin`, which
provides the utilities for retrieving and displaying a single object provides the utilities for retrieving and displaying a single object
* :class:`~django.db.views.generic.detail.SingleObjectTemplateResponseMixin`, * :class:`~django.db.views.generic.detail.SingleObjectTemplateResponseMixin`,
which provides the tools for rendering a single object into a which provides the tools for rendering a single object into a
template-based response. template-based response.
When combined, these mixins provide all the pieces necessary to When combined, these mixins provide all the pieces necessary to
provide a view over a single object that renders a template to produce provide a view over a single object that renders a template to produce
@ -192,9 +192,9 @@ SingleObjectMixin
**Context** **Context**
* ``object``: The object that this view is displaying. If * ``object``: The object that this view is displaying. If
``context_object_name`` is specified, that variable will also be ``context_object_name`` is specified, that variable will also be
set in the context, with the same value as ``object``. set in the context, with the same value as ``object``.
SingleObjectTemplateResponseMixin SingleObjectTemplateResponseMixin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -210,7 +210,7 @@ SingleObjectTemplateResponseMixin
**Extends** **Extends**
* :class:`~django.views.generic.base.TemplateResponseMixin` * :class:`~django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name_field .. attribute:: template_name_field
@ -229,10 +229,10 @@ SingleObjectTemplateResponseMixin
Returns a list of candidate template names. Returns the following list: Returns a list of candidate template names. Returns the following list:
* the value of ``template_name`` on the view (if provided) * the value of ``template_name`` on the view (if provided)
* the contents of the ``template_name_field`` field on the * the contents of the ``template_name_field`` field on the
object instance that the view is operating upon (if available) object instance that the view is operating upon (if available)
* ``<app_label>/<object_name><template_name_suffix>.html`` * ``<app_label>/<object_name><template_name_suffix>.html``
Multiple object mixins Multiple object mixins
---------------------- ----------------------
@ -248,15 +248,15 @@ MultipleObjectMixin
If ``paginate_by`` is specified, Django will paginate the results returned If ``paginate_by`` is specified, Django will paginate the results returned
by this. You can specify the page number in the URL in one of two ways: by this. You can specify the page number in the URL in one of two ways:
* Use the ``page`` parameter in the URLconf. For example, this is what * Use the ``page`` parameter in the URLconf. For example, this is what
your URLconf might look like:: your URLconf might look like::
(r'^objects/page(?P<page>[0-9]+)/$', PaginatedView.as_view()) (r'^objects/page(?P<page>[0-9]+)/$', PaginatedView.as_view())
* Pass the page number via the ``page`` query-string parameter. For * Pass the page number via the ``page`` query-string parameter. For
example, a URL would look like this:: example, a URL would look like this::
/objects/?page=3 /objects/?page=3
These values and lists are 1-based, not 0-based, so the first page would be These values and lists are 1-based, not 0-based, so the first page would be
represented as page ``1``. represented as page ``1``.
@ -363,22 +363,22 @@ MultipleObjectMixin
**Context** **Context**
* ``object_list``: The list of objects that this view is displaying. If * ``object_list``: The list of objects that this view is displaying. If
``context_object_name`` is specified, that variable will also be set ``context_object_name`` is specified, that variable will also be set
in the context, with the same value as ``object_list``. in the context, with the same value as ``object_list``.
* ``is_paginated``: A boolean representing whether the results are * ``is_paginated``: A boolean representing whether the results are
paginated. Specifically, this is set to ``False`` if no page size has paginated. Specifically, this is set to ``False`` if no page size has
been specified, or if the available objects do not span multiple been specified, or if the available objects do not span multiple
pages. pages.
* ``paginator``: An instance of * ``paginator``: An instance of
:class:`django.core.paginator.Paginator`. If the page is not :class:`django.core.paginator.Paginator`. If the page is not
paginated, this context variable will be ``None``. paginated, this context variable will be ``None``.
* ``page_obj``: An instance of * ``page_obj``: An instance of
:class:`django.core.paginator.Page`. If the page is not paginated, :class:`django.core.paginator.Page`. If the page is not paginated,
this context variable will be ``None``. this context variable will be ``None``.
MultipleObjectTemplateResponseMixin MultipleObjectTemplateResponseMixin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -392,7 +392,7 @@ MultipleObjectTemplateResponseMixin
**Extends** **Extends**
* :class:`~django.views.generic.base.TemplateResponseMixin` * :class:`~django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name_suffix .. attribute:: template_name_suffix
@ -403,8 +403,8 @@ MultipleObjectTemplateResponseMixin
Returns a list of candidate template names. Returns the following list: Returns a list of candidate template names. Returns the following list:
* the value of ``template_name`` on the view (if provided) * the value of ``template_name`` on the view (if provided)
* ``<app_label>/<object_name><template_name_suffix>.html`` * ``<app_label>/<object_name><template_name_suffix>.html``
Editing mixins Editing mixins
-------------- --------------
@ -471,7 +471,7 @@ FormMixin
**Context** **Context**
* ``form``: The form instance that was generated for the view. * ``form``: The form instance that was generated for the view.
.. note:: .. note::
@ -495,8 +495,8 @@ ModelFormMixin
**Mixins** **Mixins**
* :class:`django.views.generic.edit.FormMixin` * :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.detail.SingleObjectMixin` * :class:`django.views.generic.detail.SingleObjectMixin`
.. attribute:: success_url .. attribute:: success_url
@ -604,9 +604,9 @@ YearMixin
Returns the year for which this view will display data. Tries the Returns the year for which this view will display data. Tries the
following sources, in order: following sources, in order:
* The value of the :attr:`YearMixin.year` attribute. * The value of the :attr:`YearMixin.year` attribute.
* The value of the `year` argument captured in the URL pattern * The value of the `year` argument captured in the URL pattern
* The value of the `year` GET query argument. * The value of the `year` GET query argument.
Raises a 404 if no valid year specification can be found. Raises a 404 if no valid year specification can be found.
@ -637,9 +637,9 @@ MonthMixin
Returns the month for which this view will display data. Tries the Returns the month for which this view will display data. Tries the
following sources, in order: following sources, in order:
* The value of the :attr:`MonthMixin.month` attribute. * The value of the :attr:`MonthMixin.month` attribute.
* The value of the `month` argument captured in the URL pattern * The value of the `month` argument captured in the URL pattern
* The value of the `month` GET query argument. * The value of the `month` GET query argument.
Raises a 404 if no valid month specification can be found. Raises a 404 if no valid month specification can be found.
@ -683,9 +683,9 @@ DayMixin
Returns the day for which this view will display data. Tries the Returns the day for which this view will display data. Tries the
following sources, in order: following sources, in order:
* The value of the :attr:`DayMixin.day` attribute. * The value of the :attr:`DayMixin.day` attribute.
* The value of the `day` argument captured in the URL pattern * The value of the `day` argument captured in the URL pattern
* The value of the `day` GET query argument. * The value of the `day` GET query argument.
Raises a 404 if no valid day specification can be found. Raises a 404 if no valid day specification can be found.
@ -728,9 +728,9 @@ WeekMixin
Returns the week for which this view will display data. Tries the Returns the week for which this view will display data. Tries the
following sources, in order: following sources, in order:
* The value of the :attr:`WeekMixin.week` attribute. * The value of the :attr:`WeekMixin.week` attribute.
* The value of the `week` argument captured in the URL pattern * The value of the `week` argument captured in the URL pattern
* The value of the `week` GET query argument. * The value of the `week` GET query argument.
Raises a 404 if no valid week specification can be found. Raises a 404 if no valid week specification can be found.
@ -782,8 +782,8 @@ BaseDateListView
**Mixins** **Mixins**
* :class:`~django.views.generic.dates.DateMixin` * :class:`~django.views.generic.dates.DateMixin`
* :class:`~django.views.generic.list.MultipleObjectMixin` * :class:`~django.views.generic.list.MultipleObjectMixin`
.. attribute:: allow_empty .. attribute:: allow_empty
@ -888,7 +888,7 @@ TemplateView
**Mixins** **Mixins**
* :class:`django.views.generic.base.TemplateResponseMixin` * :class:`django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name .. attribute:: template_name
@ -901,8 +901,8 @@ TemplateView
**Context** **Context**
* ``params``: The dictionary of keyword arguments captured from the URL * ``params``: The dictionary of keyword arguments captured from the URL
pattern that served the view. pattern that served the view.
RedirectView RedirectView
~~~~~~~~~~~~ ~~~~~~~~~~~~
@ -971,8 +971,8 @@ DetailView
**Mixins** **Mixins**
* :class:`django.views.generic.detail.SingleObjectMixin` * :class:`django.views.generic.detail.SingleObjectMixin`
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin` * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
List views List views
---------- ----------
@ -997,8 +997,8 @@ ListView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectMixin` * :class:`django.views.generic.list.MultipleObjectMixin`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
Editing views Editing views
@ -1020,8 +1020,8 @@ FormView
**Mixins** **Mixins**
* :class:`django.views.generic.edit.FormMixin` * :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.edit.ProcessFormView`
CreateView CreateView
~~~~~~~~~~ ~~~~~~~~~~
@ -1037,8 +1037,8 @@ CreateView
**Mixins** **Mixins**
* :class:`django.views.generic.edit.ModelFormMixin` * :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.edit.ProcessFormView`
UpdateView UpdateView
~~~~~~~~~~ ~~~~~~~~~~
@ -1056,8 +1056,8 @@ UpdateView
**Mixins** **Mixins**
* :class:`django.views.generic.edit.ModelFormMixin` * :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.edit.ProcessFormView`
DeleteView DeleteView
~~~~~~~~~~ ~~~~~~~~~~
@ -1075,13 +1075,13 @@ DeleteView
**Mixins** **Mixins**
* :class:`django.views.generic.edit.DeletionMixin` * :class:`django.views.generic.edit.DeletionMixin`
* :class:`django.views.generic.detail.BaseDetailView` * :class:`django.views.generic.detail.BaseDetailView`
**Notes** **Notes**
* The delete confirmation page displayed to a GET request uses a * The delete confirmation page displayed to a GET request uses a
``template_name_suffix`` of ``'_confirm_delete'``. ``template_name_suffix`` of ``'_confirm_delete'``.
Date-based views Date-based views
---------------- ----------------
@ -1107,13 +1107,13 @@ ArchiveIndexView
**Mixins** **Mixins**
* :class:`django.views.generic.dates.BaseDateListView` * :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
**Notes** **Notes**
* Uses a default ``context_object_name`` of ``latest``. * Uses a default ``context_object_name`` of ``latest``.
* Uses a default ``template_name_suffix`` of ``_archive``. * Uses a default ``template_name_suffix`` of ``_archive``.
YearArchiveView YearArchiveView
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -1131,9 +1131,9 @@ YearArchiveView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin` * :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.BaseDateListView` * :class:`django.views.generic.dates.BaseDateListView`
.. attribute:: make_object_list .. attribute:: make_object_list
@ -1154,15 +1154,15 @@ YearArchiveView
:class:`django.views.generic.dates.BaseDateListView`), the template's :class:`django.views.generic.dates.BaseDateListView`), the template's
context will be: context will be:
* ``date_list``: A ``DateQuerySet`` object containing all months that * ``date_list``: A ``DateQuerySet`` object containing all months that
have objects available according to ``queryset``, represented as have objects available according to ``queryset``, represented as
``datetime.datetime`` objects, in ascending order. ``datetime.datetime`` objects, in ascending order.
* ``year``: The given year, as a four-character string. * ``year``: The given year, as a four-character string.
**Notes** **Notes**
* Uses a default ``template_name_suffix`` of ``_archive_year``. * Uses a default ``template_name_suffix`` of ``_archive_year``.
MonthArchiveView MonthArchiveView
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -1181,10 +1181,10 @@ MonthArchiveView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin` * :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin` * :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView` * :class:`django.views.generic.dates.BaseDateListView`
**Context** **Context**
@ -1193,23 +1193,23 @@ MonthArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's :class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be: context will be:
* ``date_list``: A ``DateQuerySet`` object containing all days that * ``date_list``: A ``DateQuerySet`` object containing all days that
have objects available in the given month, according to ``queryset``, have objects available in the given month, according to ``queryset``,
represented as ``datetime.datetime`` objects, in ascending order. represented as ``datetime.datetime`` objects, in ascending order.
* ``month``: A ``datetime.date`` object representing the given month. * ``month``: A ``datetime.date`` object representing the given month.
* ``next_month``: A ``datetime.date`` object representing the first day * ``next_month``: A ``datetime.date`` object representing the first day
of the next month. If the next month is in the future, this will be of the next month. If the next month is in the future, this will be
``None``. ``None``.
* ``previous_month``: A ``datetime.date`` object representing the first * ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be day of the previous month. Unlike ``next_month``, this will never be
``None``. ``None``.
**Notes** **Notes**
* Uses a default ``template_name_suffix`` of ``_archive_month``. * Uses a default ``template_name_suffix`` of ``_archive_month``.
WeekArchiveView WeekArchiveView
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -1227,10 +1227,10 @@ WeekArchiveView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin` * :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin` * :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView` * :class:`django.views.generic.dates.BaseDateListView`
**Context** **Context**
@ -1239,12 +1239,12 @@ WeekArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's :class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be: context will be:
* ``week``: A ``datetime.date`` object representing the first day of * ``week``: A ``datetime.date`` object representing the first day of
the given week. the given week.
**Notes** **Notes**
* Uses a default ``template_name_suffix`` of ``_archive_week``. * Uses a default ``template_name_suffix`` of ``_archive_week``.
DayArchiveView DayArchiveView
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -1262,11 +1262,11 @@ DayArchiveView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin` * :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin` * :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.DayMixin` * :class:`django.views.generic.dates.DayMixin`
* :class:`django.views.generic.dates.BaseDateListView` * :class:`django.views.generic.dates.BaseDateListView`
**Context** **Context**
@ -1275,25 +1275,25 @@ DayArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's :class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be: context will be:
* ``day``: A ``datetime.date`` object representing the given day. * ``day``: A ``datetime.date`` object representing the given day.
* ``next_day``: A ``datetime.date`` object representing the next day. * ``next_day``: A ``datetime.date`` object representing the next day.
If the next day is in the future, this will be ``None``. If the next day is in the future, this will be ``None``.
* ``previous_day``: A ``datetime.date`` object representing the * ``previous_day``: A ``datetime.date`` object representing the
previous day. Unlike ``next_day``, this will never be ``None``. previous day. Unlike ``next_day``, this will never be ``None``.
* ``next_month``: A ``datetime.date`` object representing the first day * ``next_month``: A ``datetime.date`` object representing the first day
of the next month. If the next month is in the future, this will be of the next month. If the next month is in the future, this will be
``None``. ``None``.
* ``previous_month``: A ``datetime.date`` object representing the first * ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be day of the previous month. Unlike ``next_month``, this will never be
``None``. ``None``.
**Notes** **Notes**
* Uses a default ``template_name_suffix`` of ``_archive_day``. * Uses a default ``template_name_suffix`` of ``_archive_day``.
TodayArchiveView TodayArchiveView
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -1311,8 +1311,8 @@ TodayArchiveView
**Mixins** **Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin` * :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.BaseDayArchiveView` * :class:`django.views.generic.dates.BaseDayArchiveView`
DateDetailView DateDetailView
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -1330,9 +1330,9 @@ DateDetailView
**Mixins** **Mixins**
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin` * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
* :class:`django.views.generic.detail.BaseDetailView` * :class:`django.views.generic.detail.BaseDetailView`
* :class:`django.views.generic.dates.DateMixin` * :class:`django.views.generic.dates.DateMixin`
* :class:`django.views.generic.dates.YearMixin` * :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin` * :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.DayMixin` * :class:`django.views.generic.dates.DayMixin`

View File

@ -73,10 +73,10 @@ First, we'll need to write a function that gets called when the action is
trigged from the admin. Action functions are just regular functions that take trigged from the admin. Action functions are just regular functions that take
three arguments: three arguments:
* The current :class:`ModelAdmin` * The current :class:`ModelAdmin`
* An :class:`~django.http.HttpRequest` representing the current request, * An :class:`~django.http.HttpRequest` representing the current request,
* A :class:`~django.db.models.query.QuerySet` containing the set of * A :class:`~django.db.models.query.QuerySet` containing the set of
objects selected by the user. objects selected by the user.
Our publish-these-articles function won't need the :class:`ModelAdmin` or the Our publish-these-articles function won't need the :class:`ModelAdmin` or the
request object, but we will use the queryset:: request object, but we will use the queryset::

View File

@ -22,16 +22,16 @@ Overview
To activate the :mod:`~django.contrib.admindocs`, you will need to do To activate the :mod:`~django.contrib.admindocs`, you will need to do
the following: the following:
* Add :mod:`django.contrib.admindocs` to your :setting:`INSTALLED_APPS`. * Add :mod:`django.contrib.admindocs` to your :setting:`INSTALLED_APPS`.
* Add ``(r'^admin/doc/', include('django.contrib.admindocs.urls'))`` to * Add ``(r'^admin/doc/', include('django.contrib.admindocs.urls'))`` to
your :data:`urlpatterns`. Make sure it's included *before* the your :data:`urlpatterns`. Make sure it's included *before* the
``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get ``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get
handled by the latter entry. handled by the latter entry.
* Install the docutils Python module (http://docutils.sf.net/). * Install the docutils Python module (http://docutils.sf.net/).
* **Optional:** Linking to templates requires the :setting:`ADMIN_FOR` * **Optional:** Linking to templates requires the :setting:`ADMIN_FOR`
setting to be configured. setting to be configured.
* **Optional:** Using the admindocs bookmarklets requires the * **Optional:** Using the admindocs bookmarklets requires the
:mod:`XViewMiddleware<django.middleware.doc>` to be installed. :mod:`XViewMiddleware<django.middleware.doc>` to be installed.
Once those steps are complete, you can start browsing the documentation by Once those steps are complete, you can start browsing the documentation by
going to your admin interface and clicking the "Documentation" link in the going to your admin interface and clicking the "Documentation" link in the
@ -85,9 +85,9 @@ Each URL in your site has a separate entry in the ``admindocs`` page, and
clicking on a given URL will show you the corresponding view. Helpful things clicking on a given URL will show you the corresponding view. Helpful things
you can document in your view function docstrings include: you can document in your view function docstrings include:
* A short description of what the view does. * A short description of what the view does.
* The **context**, or a list of variables available in the view's template. * The **context**, or a list of variables available in the view's template.
* The name of the template or templates that are used for that view. * The name of the template or templates that are used for that view.
For example:: For example::
@ -141,16 +141,16 @@ Included Bookmarklets
Several useful bookmarklets are available from the ``admindocs`` page: Several useful bookmarklets are available from the ``admindocs`` page:
Documentation for this page Documentation for this page
Jumps you from any page to the documentation for the view that generates Jumps you from any page to the documentation for the view that generates
that page. that page.
Show object ID Show object ID
Shows the content-type and unique ID for pages that represent a single Shows the content-type and unique ID for pages that represent a single
object. object.
Edit this object Edit this object
Jumps to the admin page for pages that represent a single object. Jumps to the admin page for pages that represent a single object.
Using these bookmarklets requires that you are either logged into the Using these bookmarklets requires that you are either logged into the
:mod:`Django admin <django.contrib.admin>` as a :mod:`Django admin <django.contrib.admin>` as a
@ -158,4 +158,4 @@ Using these bookmarklets requires that you are either logged into the
:attr:`~django.contrib.auth.models.User.is_staff` set to `True`, or :attr:`~django.contrib.auth.models.User.is_staff` set to `True`, or
that the :mod:`django.middleware.doc` middleware and that the :mod:`django.middleware.doc` middleware and
:mod:`XViewMiddleware <django.middleware.doc>` are installed and you :mod:`XViewMiddleware <django.middleware.doc>` are installed and you
are accessing the site from an IP address listed in :setting:`INTERNAL_IPS`. are accessing the site from an IP address listed in :setting:`INTERNAL_IPS`.

View File

@ -41,14 +41,14 @@ comment model has no field for that title.
To make this kind of customization, we'll need to do three things: To make this kind of customization, we'll need to do three things:
#. Create a custom comment :class:`~django.db.models.Model` that adds on the #. Create a custom comment :class:`~django.db.models.Model` that adds on the
"title" field. "title" field.
#. Create a custom comment :class:`~django.forms.Form` that also adds this #. Create a custom comment :class:`~django.forms.Form` that also adds this
"title" field. "title" field.
#. Inform Django of these objects by defining a few functions in a #. Inform Django of these objects by defining a few functions in a
custom :setting:`COMMENTS_APP`. custom :setting:`COMMENTS_APP`.
So, carrying on the example above, we're dealing with a typical app structure in So, carrying on the example above, we're dealing with a typical app structure in
the ``my_custom_app`` directory:: the ``my_custom_app`` directory::

View File

@ -22,23 +22,23 @@ Quick start guide
To get started using the ``comments`` app, follow these steps: To get started using the ``comments`` app, follow these steps:
#. Install the comments framework by adding ``'django.contrib.comments'`` to #. Install the comments framework by adding ``'django.contrib.comments'`` to
:setting:`INSTALLED_APPS`. :setting:`INSTALLED_APPS`.
#. Run ``manage.py syncdb`` so that Django will create the comment tables. #. Run ``manage.py syncdb`` so that Django will create the comment tables.
#. Add the comment app's URLs to your project's ``urls.py``: #. Add the comment app's URLs to your project's ``urls.py``:
.. code-block:: python .. code-block:: python
urlpatterns = patterns('', urlpatterns = patterns('',
... ...
(r'^comments/', include('django.contrib.comments.urls')), (r'^comments/', include('django.contrib.comments.urls')),
... ...
) )
#. Use the `comment template tags`_ below to embed comments in your #. Use the `comment template tags`_ below to embed comments in your
templates. templates.
You might also want to examine :doc:`/ref/contrib/comments/settings`. You might also want to examine :doc:`/ref/contrib/comments/settings`.
@ -62,25 +62,25 @@ Django's comments are all "attached" to some parent object. This can be any
instance of a Django model. Each of the tags below gives you a couple of instance of a Django model. Each of the tags below gives you a couple of
different ways you can specify which object to attach to: different ways you can specify which object to attach to:
#. Refer to the object directly -- the more common method. Most of the #. Refer to the object directly -- the more common method. Most of the
time, you'll have some object in the template's context you want time, you'll have some object in the template's context you want
to attach the comment to; you can simply use that object. to attach the comment to; you can simply use that object.
For example, in a blog entry page that has a variable named ``entry``, For example, in a blog entry page that has a variable named ``entry``,
you could use the following to load the number of comments:: you could use the following to load the number of comments::
{% get_comment_count for entry as comment_count %}. {% get_comment_count for entry as comment_count %}.
#. Refer to the object by content-type and object id. You'd use this method #. Refer to the object by content-type and object id. You'd use this method
if you, for some reason, don't actually have direct access to the object. if you, for some reason, don't actually have direct access to the object.
Following the above example, if you knew the object ID was ``14`` but Following the above example, if you knew the object ID was ``14`` but
didn't have access to the actual object, you could do something like:: didn't have access to the actual object, you could do something like::
{% get_comment_count for blog.entry 14 as comment_count %} {% get_comment_count for blog.entry 14 as comment_count %}
In the above, ``blog.entry`` is the app label and (lower-cased) model In the above, ``blog.entry`` is the app label and (lower-cased) model
name of the model class. name of the model class.
Displaying comments Displaying comments
------------------- -------------------
@ -262,25 +262,25 @@ Notes on the comment form
The form used by the comment system has a few important anti-spam attributes you The form used by the comment system has a few important anti-spam attributes you
should know about: should know about:
* It contains a number of hidden fields that contain timestamps, information * It contains a number of hidden fields that contain timestamps, information
about the object the comment should be attached to, and a "security hash" about the object the comment should be attached to, and a "security hash"
used to validate this information. If someone tampers with this data -- used to validate this information. If someone tampers with this data --
something comment spammers will try -- the comment submission will fail. something comment spammers will try -- the comment submission will fail.
If you're rendering a custom comment form, you'll need to make sure to If you're rendering a custom comment form, you'll need to make sure to
pass these values through unchanged. pass these values through unchanged.
* The timestamp is used to ensure that "reply attacks" can't continue very * The timestamp is used to ensure that "reply attacks" can't continue very
long. Users who wait too long between requesting the form and posting a long. Users who wait too long between requesting the form and posting a
comment will have their submissions refused. comment will have their submissions refused.
* The comment form includes a "honeypot_" field. It's a trap: if any data is * The comment form includes a "honeypot_" field. It's a trap: if any data is
entered in that field, the comment will be considered spam (spammers often entered in that field, the comment will be considered spam (spammers often
automatically fill in all fields in an attempt to make valid submissions). automatically fill in all fields in an attempt to make valid submissions).
The default form hides this field with a piece of CSS and further labels The default form hides this field with a piece of CSS and further labels
it with a warning field; if you use the comment form with a custom it with a warning field; if you use the comment form with a custom
template you should be sure to do the same. template you should be sure to do the same.
The comments app also depends on the more general :doc:`Cross Site Request The comments app also depends on the more general :doc:`Cross Site Request
Forgery protection </ref/contrib/csrf>` that comes with Django. As described in Forgery protection </ref/contrib/csrf>` that comes with Django. As described in

View File

@ -27,38 +27,38 @@ This signal is sent at more or less the same time (just before, actually) as the
``Comment`` object's :data:`~django.db.models.signals.pre_save` signal. ``Comment`` object's :data:`~django.db.models.signals.pre_save` signal.
Arguments sent with this signal: Arguments sent with this signal:
``sender`` ``sender``
The comment model. The comment model.
``comment`` ``comment``
The comment instance about to be posted. Note that it won't have been The comment instance about to be posted. Note that it won't have been
saved into the database yet, so it won't have a primary key, and any saved into the database yet, so it won't have a primary key, and any
relations might not work correctly yet. relations might not work correctly yet.
``request`` ``request``
The :class:`~django.http.HttpRequest` that posted the comment. The :class:`~django.http.HttpRequest` that posted the comment.
comment_was_posted comment_was_posted
================== ==================
.. data:: django.contrib.comments.signals.comment_was_posted .. data:: django.contrib.comments.signals.comment_was_posted
:module: :module:
Sent just after the comment is saved. Sent just after the comment is saved.
Arguments sent with this signal: Arguments sent with this signal:
``sender`` ``sender``
The comment model. The comment model.
``comment`` ``comment``
The comment instance that was posted. Note that it will have already The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again. :meth:`~django.db.models.Model.save` again.
``request`` ``request``
The :class:`~django.http.HttpRequest` that posted the comment. The :class:`~django.http.HttpRequest` that posted the comment.
comment_was_flagged comment_was_flagged
=================== ===================
@ -71,21 +71,21 @@ was a user requesting removal of a comment, a moderator approving/removing a
comment, or some other custom user flag. comment, or some other custom user flag.
Arguments sent with this signal: Arguments sent with this signal:
``sender`` ``sender``
The comment model. The comment model.
``comment`` ``comment``
The comment instance that was posted. Note that it will have already The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again. :meth:`~django.db.models.Model.save` again.
``flag`` ``flag``
The :class:`~django.contrib.comments.models.CommentFlag` that's been The :class:`~django.contrib.comments.models.CommentFlag` that's been
attached to the comment. attached to the comment.
``created`` ``created``
``True`` if this is a new flag; ``False`` if it's a duplicate flag. ``True`` if this is a new flag; ``False`` if it's a duplicate flag.
``request`` ``request``
The :class:`~django.http.HttpRequest` that posted the comment. The :class:`~django.http.HttpRequest` that posted the comment.

View File

@ -7,31 +7,31 @@ new comment system; this guide explains how.
The main changes from the old system are: The main changes from the old system are:
* This new system is documented. * This new system is documented.
* It uses modern Django features like :doc:`forms </topics/forms/index>` and
:doc:`modelforms </topics/forms/modelforms>`.
* It has a single ``Comment`` model instead of separate ``FreeComment`` and * It uses modern Django features like :doc:`forms </topics/forms/index>` and
``Comment`` models. :doc:`modelforms </topics/forms/modelforms>`.
* Comments have "email" and "URL" fields. * It has a single ``Comment`` model instead of separate ``FreeComment`` and
``Comment`` models.
* No ratings, photos and karma. This should only effect World Online. * Comments have "email" and "URL" fields.
* The ``{% comment_form %}`` tag no longer exists. Instead, there's now two * No ratings, photos and karma. This should only effect World Online.
functions: ``{% get_comment_form %}``, which returns a form for posting a
new comment, and ``{% render_comment_form %}``, which renders said form
using the ``comments/form.html`` template.
* The way comments are include in your URLconf have changed; you'll need to
replace::
(r'^comments/', include('django.contrib.comments.urls.comments')),
with::
(r'^comments/', include('django.contrib.comments.urls')), * The ``{% comment_form %}`` tag no longer exists. Instead, there's now two
functions: ``{% get_comment_form %}``, which returns a form for posting a
new comment, and ``{% render_comment_form %}``, which renders said form
using the ``comments/form.html`` template.
* The way comments are include in your URLconf have changed; you'll need to
replace::
(r'^comments/', include('django.contrib.comments.urls.comments')),
with::
(r'^comments/', include('django.contrib.comments.urls')),
Upgrading data Upgrading data
-------------- --------------

View File

@ -45,14 +45,14 @@ but if you've removed it or if you manually set up your
It's generally a good idea to have the contenttypes framework It's generally a good idea to have the contenttypes framework
installed; several of Django's other bundled applications require it: installed; several of Django's other bundled applications require it:
* The admin application uses it to log the history of each object * The admin application uses it to log the history of each object
added or changed through the admin interface. added or changed through the admin interface.
* Django's :mod:`authentication framework <django.contrib.auth>` uses it * Django's :mod:`authentication framework <django.contrib.auth>` uses it
to tie user permissions to specific models. to tie user permissions to specific models.
* Django's comments system (:mod:`django.contrib.comments`) uses it to * Django's comments system (:mod:`django.contrib.comments`) uses it to
"attach" comments to any installed model. "attach" comments to any installed model.
.. currentmodule:: django.contrib.contenttypes.models .. currentmodule:: django.contrib.contenttypes.models
@ -92,15 +92,15 @@ your database. Along with it a new instance of
:class:`~django.contrib.contenttypes.models.ContentType` will be :class:`~django.contrib.contenttypes.models.ContentType` will be
created with the following values: created with the following values:
* :attr:`~django.contrib.contenttypes.models.ContentType.app_label` * :attr:`~django.contrib.contenttypes.models.ContentType.app_label`
will be set to ``'sites'`` (the last part of the Python will be set to ``'sites'`` (the last part of the Python
path "django.contrib.sites"). path "django.contrib.sites").
* :attr:`~django.contrib.contenttypes.models.ContentType.model` * :attr:`~django.contrib.contenttypes.models.ContentType.model`
will be set to ``'site'``. will be set to ``'site'``.
* :attr:`~django.contrib.contenttypes.models.ContentType.name` * :attr:`~django.contrib.contenttypes.models.ContentType.name`
will be set to ``'site'``. will be set to ``'site'``.
.. _the verbose_name attribute: ../model-api/#verbose_name .. _the verbose_name attribute: ../model-api/#verbose_name
@ -148,17 +148,17 @@ Together,
and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable
two extremely important use cases: two extremely important use cases:
1. Using these methods, you can write high-level generic code that 1. Using these methods, you can write high-level generic code that
performs queries on any installed model -- instead of importing and performs queries on any installed model -- instead of importing and
using a single specific model class, you can pass an ``app_label`` and using a single specific model class, you can pass an ``app_label`` and
``model`` into a ``model`` into a
:class:`~django.contrib.contenttypes.models.ContentType` lookup at :class:`~django.contrib.contenttypes.models.ContentType` lookup at
runtime, and then work with the model class or retrieve objects from it. runtime, and then work with the model class or retrieve objects from it.
2. You can relate another model to 2. You can relate another model to
:class:`~django.contrib.contenttypes.models.ContentType` as a way of :class:`~django.contrib.contenttypes.models.ContentType` as a way of
tying instances of it to particular model classes, and use these methods tying instances of it to particular model classes, and use these methods
to get access to those model classes. to get access to those model classes.
Several of Django's bundled applications make use of the latter technique. Several of Django's bundled applications make use of the latter technique.
For example, For example,
@ -263,21 +263,21 @@ model:
There are three parts to setting up a There are three parts to setting up a
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`: :class:`~django.contrib.contenttypes.generic.GenericForeignKey`:
1. Give your model a :class:`~django.db.models.ForeignKey` 1. Give your model a :class:`~django.db.models.ForeignKey`
to :class:`~django.contrib.contenttypes.models.ContentType`. to :class:`~django.contrib.contenttypes.models.ContentType`.
2. Give your model a field that can store primary key values from the 2. Give your model a field that can store primary key values from the
models you'll be relating to. For most models, this means a models you'll be relating to. For most models, this means a
:class:`~django.db.models.PositiveIntegerField`. The usual name :class:`~django.db.models.PositiveIntegerField`. The usual name
for this field is "object_id". for this field is "object_id".
3. Give your model a 3. Give your model a
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and
pass it the names of the two fields described above. If these fields pass it the names of the two fields described above. If these fields
are named "content_type" and "object_id", you can omit this -- those are named "content_type" and "object_id", you can omit this -- those
are the default field names are the default field names
:class:`~django.contrib.contenttypes.generic.GenericForeignKey` will :class:`~django.contrib.contenttypes.generic.GenericForeignKey` will
look for. look for.
.. admonition:: Primary key type compatibility .. admonition:: Primary key type compatibility

View File

@ -28,49 +28,49 @@ How to use it
To enable CSRF protection for your views, follow these steps: To enable CSRF protection for your views, follow these steps:
1. Add the middleware 1. Add the middleware
``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of ``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of
middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come
before any view middleware that assume that CSRF attacks have before any view middleware that assume that CSRF attacks have
been dealt with.) been dealt with.)
Alternatively, you can use the decorator Alternatively, you can use the decorator
:func:`~django.views.decorators.csrf.csrf_protect` on particular views :func:`~django.views.decorators.csrf.csrf_protect` on particular views
you want to protect (see below). you want to protect (see below).
2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside 2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside
the ``<form>`` element if the form is for an internal URL, e.g.:: the ``<form>`` element if the form is for an internal URL, e.g.::
<form action="." method="post">{% csrf_token %} <form action="." method="post">{% csrf_token %}
This should not be done for POST forms that target external URLs, since This should not be done for POST forms that target external URLs, since
that would cause the CSRF token to be leaked, leading to a vulnerability. that would cause the CSRF token to be leaked, leading to a vulnerability.
3. In the corresponding view functions, ensure that the 3. In the corresponding view functions, ensure that the
``'django.core.context_processors.csrf'`` context processor is ``'django.core.context_processors.csrf'`` context processor is
being used. Usually, this can be done in one of two ways: being used. Usually, this can be done in one of two ways:
1. Use RequestContext, which always uses 1. Use RequestContext, which always uses
``'django.core.context_processors.csrf'`` (no matter what your ``'django.core.context_processors.csrf'`` (no matter what your
TEMPLATE_CONTEXT_PROCESSORS setting). If you are using TEMPLATE_CONTEXT_PROCESSORS setting). If you are using
generic views or contrib apps, you are covered already, since these generic views or contrib apps, you are covered already, since these
apps use RequestContext throughout. apps use RequestContext throughout.
2. Manually import and use the processor to generate the CSRF token and 2. Manually import and use the processor to generate the CSRF token and
add it to the template context. e.g.:: add it to the template context. e.g.::
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
def my_view(request): def my_view(request):
c = {} c = {}
c.update(csrf(request)) c.update(csrf(request))
# ... view code here # ... view code here
return render_to_response("a_template.html", c) return render_to_response("a_template.html", c)
You may want to write your own You may want to write your own
:func:`~django.shortcuts.render_to_response()` wrapper that takes care :func:`~django.shortcuts.render_to_response()` wrapper that takes care
of this step for you. of this step for you.
The utility script ``extras/csrf_migration_helper.py`` can help to automate the The utility script ``extras/csrf_migration_helper.py`` can help to automate the
finding of code and templates that may need these steps. It contains full help finding of code and templates that may need these steps. It contains full help

View File

@ -17,45 +17,45 @@ introspecting your models.
How to use Databrowse How to use Databrowse
===================== =====================
1. Point Django at the default Databrowse templates. There are two ways to 1. Point Django at the default Databrowse templates. There are two ways to
do this: do this:
* Add ``'django.contrib.databrowse'`` to your :setting:`INSTALLED_APPS` * Add ``'django.contrib.databrowse'`` to your :setting:`INSTALLED_APPS`
setting. This will work if your :setting:`TEMPLATE_LOADERS` setting setting. This will work if your :setting:`TEMPLATE_LOADERS` setting
includes the ``app_directories`` template loader (which is the case by includes the ``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>` for default). See the :ref:`template loader docs <template-loaders>` for
more. more.
* Otherwise, determine the full filesystem path to the * Otherwise, determine the full filesystem path to the
:file:`django/contrib/databrowse/templates` directory, and add that :file:`django/contrib/databrowse/templates` directory, and add that
directory to your :setting:`TEMPLATE_DIRS` setting. directory to your :setting:`TEMPLATE_DIRS` setting.
2. Register a number of models with the Databrowse site:: 2. Register a number of models with the Databrowse site::
from django.contrib import databrowse from django.contrib import databrowse
from myapp.models import SomeModel, SomeOtherModel from myapp.models import SomeModel, SomeOtherModel
databrowse.site.register(SomeModel) databrowse.site.register(SomeModel)
databrowse.site.register(SomeOtherModel) databrowse.site.register(SomeOtherModel)
Note that you should register the model *classes*, not instances. Note that you should register the model *classes*, not instances.
It doesn't matter where you put this, as long as it gets executed at some It doesn't matter where you put this, as long as it gets executed at some
point. A good place for it is in your :doc:`URLconf file point. A good place for it is in your :doc:`URLconf file
</topics/http/urls>` (``urls.py``). </topics/http/urls>` (``urls.py``).
3. Change your URLconf to import the :mod:`~django.contrib.databrowse` module:: 3. Change your URLconf to import the :mod:`~django.contrib.databrowse` module::
from django.contrib import databrowse from django.contrib import databrowse
...and add the following line to your URLconf:: ...and add the following line to your URLconf::
(r'^databrowse/(.*)', databrowse.site.root), (r'^databrowse/(.*)', databrowse.site.root),
The prefix doesn't matter -- you can use ``databrowse/`` or ``db/`` or The prefix doesn't matter -- you can use ``databrowse/`` or ``db/`` or
whatever you'd like. whatever you'd like.
4. Run the Django server and visit ``/databrowse/`` in your browser. 4. Run the Django server and visit ``/databrowse/`` in your browser.
Requiring user login Requiring user login
==================== ====================

View File

@ -22,30 +22,30 @@ content in a custom template.
Here are some examples of flatpages on Django-powered sites: Here are some examples of flatpages on Django-powered sites:
* http://www.lawrence.com/about/contact/ * http://www.lawrence.com/about/contact/
* http://www2.ljworld.com/site/rules/ * http://www2.ljworld.com/site/rules/
Installation Installation
============ ============
To install the flatpages app, follow these steps: To install the flatpages app, follow these steps:
1. Install the :mod:`sites framework <django.contrib.sites>` by adding 1. Install the :mod:`sites framework <django.contrib.sites>` by adding
``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting, ``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting,
if it's not already in there. if it's not already in there.
Also make sure you've correctly set :setting:`SITE_ID` to the ID of the Also make sure you've correctly set :setting:`SITE_ID` to the ID of the
site the settings file represents. This will usually be ``1`` (i.e. site the settings file represents. This will usually be ``1`` (i.e.
``SITE_ID = 1``, but if you're using the sites framework to manage ``SITE_ID = 1``, but if you're using the sites framework to manage
multiple sites, it could be the ID of a different site. multiple sites, it could be the ID of a different site.
2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS` 2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS`
setting. setting.
3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'`` 3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
to your :setting:`MIDDLEWARE_CLASSES` setting. to your :setting:`MIDDLEWARE_CLASSES` setting.
4. Run the command :djadmin:`manage.py syncdb <syncdb>`. 4. Run the command :djadmin:`manage.py syncdb <syncdb>`.
.. currentmodule:: django.contrib.flatpages.middleware .. currentmodule:: django.contrib.flatpages.middleware
@ -69,13 +69,13 @@ does all of the work.
If it finds a match, it follows this algorithm: If it finds a match, it follows this algorithm:
* If the flatpage has a custom template, it loads that template. * If the flatpage has a custom template, it loads that template.
Otherwise, it loads the template :file:`flatpages/default.html`. Otherwise, it loads the template :file:`flatpages/default.html`.
* It passes that template a single context variable, ``flatpage``, * It passes that template a single context variable, ``flatpage``,
which is the flatpage object. It uses which is the flatpage object. It uses
:class:`~django.template.RequestContext` in rendering the :class:`~django.template.RequestContext` in rendering the
template. template.
.. versionchanged:: 1.4 .. versionchanged:: 1.4
The middleware will only add a trailing slash and redirect (by looking The middleware will only add a trailing slash and redirect (by looking

View File

@ -20,14 +20,14 @@ Overview
Given a :class:`django.forms.Form` subclass that you define, this Given a :class:`django.forms.Form` subclass that you define, this
application takes care of the following workflow: application takes care of the following workflow:
1. Displays the form as HTML on a Web page. 1. Displays the form as HTML on a Web page.
2. Validates the form data when it's submitted via POST. 2. Validates the form data when it's submitted via POST.
a. If it's valid, displays a preview page. a. If it's valid, displays a preview page.
b. If it's not valid, redisplays the form with error messages. b. If it's not valid, redisplays the form with error messages.
3. When the "confirmation" form is submitted from the preview page, calls 3. When the "confirmation" form is submitted from the preview page, calls
a hook that you define -- a a hook that you define -- a
:meth:`~django.contrib.formtools.preview.FormPreview.done()` method that gets :meth:`~django.contrib.formtools.preview.FormPreview.done()` method that gets
passed the valid data. passed the valid data.
The framework enforces the required preview by passing a shared-secret hash to The framework enforces the required preview by passing a shared-secret hash to
the preview page via hidden form fields. If somebody tweaks the form parameters the preview page via hidden form fields. If somebody tweaks the form parameters
@ -36,53 +36,53 @@ on the preview page, the form submission will fail the hash-comparison test.
How to use ``FormPreview`` How to use ``FormPreview``
========================== ==========================
1. Point Django at the default FormPreview templates. There are two ways to 1. Point Django at the default FormPreview templates. There are two ways to
do this: do this:
* Add ``'django.contrib.formtools'`` to your * Add ``'django.contrib.formtools'`` to your
:setting:`INSTALLED_APPS` setting. This will work if your :setting:`INSTALLED_APPS` setting. This will work if your
:setting:`TEMPLATE_LOADERS` setting includes the :setting:`TEMPLATE_LOADERS` setting includes the
``app_directories`` template loader (which is the case by ``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>` default). See the :ref:`template loader docs <template-loaders>`
for more. for more.
* Otherwise, determine the full filesystem path to the * Otherwise, determine the full filesystem path to the
:file:`django/contrib/formtools/templates` directory, and add that :file:`django/contrib/formtools/templates` directory, and add that
directory to your :setting:`TEMPLATE_DIRS` setting. directory to your :setting:`TEMPLATE_DIRS` setting.
2. Create a :class:`~django.contrib.formtools.preview.FormPreview` subclass that 2. Create a :class:`~django.contrib.formtools.preview.FormPreview` subclass that
overrides the :meth:`~django.contrib.formtools.preview.FormPreview.done()` overrides the :meth:`~django.contrib.formtools.preview.FormPreview.done()`
method:: method::
from django.contrib.formtools.preview import FormPreview from django.contrib.formtools.preview import FormPreview
from myapp.models import SomeModel from myapp.models import SomeModel
class SomeModelFormPreview(FormPreview): class SomeModelFormPreview(FormPreview):
def done(self, request, cleaned_data): def done(self, request, cleaned_data):
# Do something with the cleaned_data, then redirect # Do something with the cleaned_data, then redirect
# to a "success" page. # to a "success" page.
return HttpResponseRedirect('/form/success') return HttpResponseRedirect('/form/success')
This method takes an :class:`~django.http.HttpRequest` object and a This method takes an :class:`~django.http.HttpRequest` object and a
dictionary of the form data after it has been validated and cleaned. dictionary of the form data after it has been validated and cleaned.
It should return an :class:`~django.http.HttpResponseRedirect` that It should return an :class:`~django.http.HttpResponseRedirect` that
is the end result of the form being submitted. is the end result of the form being submitted.
3. Change your URLconf to point to an instance of your 3. Change your URLconf to point to an instance of your
:class:`~django.contrib.formtools.preview.FormPreview` subclass:: :class:`~django.contrib.formtools.preview.FormPreview` subclass::
from myapp.preview import SomeModelFormPreview from myapp.preview import SomeModelFormPreview
from myapp.forms import SomeModelForm from myapp.forms import SomeModelForm
from django import forms from django import forms
...and add the following line to the appropriate model in your URLconf:: ...and add the following line to the appropriate model in your URLconf::
(r'^post/$', SomeModelFormPreview(SomeModelForm)), (r'^post/$', SomeModelFormPreview(SomeModelForm)),
where ``SomeModelForm`` is a Form or ModelForm class for the model. where ``SomeModelForm`` is a Form or ModelForm class for the model.
4. Run the Django server and visit :file:`/post/` in your browser. 4. Run the Django server and visit :file:`/post/` in your browser.
``FormPreview`` classes ``FormPreview`` classes
======================= =======================

View File

@ -24,15 +24,15 @@ How it works
Here's the basic workflow for how a user would use a wizard: Here's the basic workflow for how a user would use a wizard:
1. The user visits the first page of the wizard, fills in the form and 1. The user visits the first page of the wizard, fills in the form and
submits it. submits it.
2. The server validates the data. If it's invalid, the form is displayed 2. The server validates the data. If it's invalid, the form is displayed
again, with error messages. If it's valid, the server saves the current again, with error messages. If it's valid, the server saves the current
state of the wizard in the backend and redirects to the next step. state of the wizard in the backend and redirects to the next step.
3. Step 1 and 2 repeat, for every subsequent form in the wizard. 3. Step 1 and 2 repeat, for every subsequent form in the wizard.
4. Once the user has submitted all the forms and all the data has been 4. Once the user has submitted all the forms and all the data has been
validated, the wizard processes the data -- saving it to the database, validated, the wizard processes the data -- saving it to the database,
sending an email, or whatever the application needs to do. sending an email, or whatever the application needs to do.
Usage Usage
===== =====
@ -40,21 +40,21 @@ Usage
This application handles as much machinery for you as possible. Generally, This application handles as much machinery for you as possible. Generally,
you just have to do these things: you just have to do these things:
1. Define a number of :class:`~django.forms.Form` classes -- one per 1. Define a number of :class:`~django.forms.Form` classes -- one per
wizard page. wizard page.
2. Create a :class:`WizardView` subclass that specifies what to do once 2. Create a :class:`WizardView` subclass that specifies what to do once
all of your forms have been submitted and validated. This also lets all of your forms have been submitted and validated. This also lets
you override some of the wizard's behavior. you override some of the wizard's behavior.
3. Create some templates that render the forms. You can define a single, 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 generic template to handle every one of the forms, or you can define a
specific template for each form. specific template for each form.
4. Add ``django.contrib.formtools`` to your 4. Add ``django.contrib.formtools`` to your
:setting:`INSTALLED_APPS` list in your settings file. :setting:`INSTALLED_APPS` list in your settings file.
5. Point your URLconf at your :class:`WizardView` :meth:`~WizardView.as_view` method. 5. Point your URLconf at your :class:`WizardView` :meth:`~WizardView.as_view` method.
Defining ``Form`` classes Defining ``Form`` classes
------------------------- -------------------------
@ -160,21 +160,21 @@ latter one allows you to use a different template for each form.
This template expects a ``wizard`` object that has various items attached to This template expects a ``wizard`` object that has various items attached to
it: it:
* ``form`` -- The :class:`~django.forms.Form` instance for the current * ``form`` -- The :class:`~django.forms.Form` instance for the current
step (either empty or with errors). step (either empty or with errors).
* ``steps`` -- A helper object to access the various steps related data: * ``steps`` -- A helper object to access the various steps related data:
* ``step0`` -- The current step (zero-based). * ``step0`` -- The current step (zero-based).
* ``step1`` -- The current step (one-based). * ``step1`` -- The current step (one-based).
* ``count`` -- The total number of steps. * ``count`` -- The total number of steps.
* ``first`` -- The first step. * ``first`` -- The first step.
* ``last`` -- The last step. * ``last`` -- The last step.
* ``current`` -- The current (or first) step. * ``current`` -- The current (or first) step.
* ``next`` -- The next step. * ``next`` -- The next step.
* ``prev`` -- The previous step. * ``prev`` -- The previous step.
* ``index`` -- The index of the current step. * ``index`` -- The index of the current step.
* ``all`` -- A list of all steps of the wizard. * ``all`` -- A list of all steps of the wizard.
You can supply additional context variables by using the You can supply additional context variables by using the
:meth:`~WizardView.get_context_data` method of your :class:`WizardView` :meth:`~WizardView.get_context_data` method of your :class:`WizardView`
@ -582,8 +582,8 @@ Below you will see an example of a contact wizard with two steps, step 1 with
Additionally you have to pass two more arguments to the Additionally you have to pass two more arguments to the
:meth:`~WizardView.as_view` method: :meth:`~WizardView.as_view` method:
* ``url_name`` -- the name of the url (as provided in the urls.py) * ``url_name`` -- the name of the url (as provided in the urls.py)
* ``done_step_name`` -- the name in the url for the done step * ``done_step_name`` -- the name in the url for the done step
Example code for the changed ``urls.py`` file:: Example code for the changed ``urls.py`` file::

View File

@ -23,9 +23,9 @@ number. This follows Associated Press style.
Examples: Examples:
* ``1`` becomes ``one``. * ``1`` becomes ``one``.
* ``2`` becomes ``two``. * ``2`` becomes ``two``.
* ``10`` becomes ``10``. * ``10`` becomes ``10``.
You can pass in either an integer or a string representation of an integer. You can pass in either an integer or a string representation of an integer.
@ -38,16 +38,16 @@ Converts an integer to a string containing commas every three digits.
Examples: Examples:
* ``4500`` becomes ``4,500``. * ``4500`` becomes ``4,500``.
* ``45000`` becomes ``45,000``. * ``45000`` becomes ``45,000``.
* ``450000`` becomes ``450,000``. * ``450000`` becomes ``450,000``.
* ``4500000`` becomes ``4,500,000``. * ``4500000`` becomes ``4,500,000``.
:ref:`Format localization <format-localization>` will be respected if enabled, :ref:`Format localization <format-localization>` will be respected if enabled,
e.g. with the ``'de'`` language: e.g. with the ``'de'`` language:
* ``45000`` becomes ``'45.000'``. * ``45000`` becomes ``'45.000'``.
* ``450000`` becomes ``'450.000'``. * ``450000`` becomes ``'450.000'``.
You can pass in either an integer or a string representation of an integer. You can pass in either an integer or a string representation of an integer.
@ -61,18 +61,18 @@ numbers over 1 million.
Examples: Examples:
* ``1000000`` becomes ``1.0 million``. * ``1000000`` becomes ``1.0 million``.
* ``1200000`` becomes ``1.2 million``. * ``1200000`` becomes ``1.2 million``.
* ``1200000000`` becomes ``1.2 billion``. * ``1200000000`` becomes ``1.2 billion``.
Values up to 10^100 (Googol) are supported. Values up to 10^100 (Googol) are supported.
:ref:`Format localization <format-localization>` will be respected if enabled, :ref:`Format localization <format-localization>` will be respected if enabled,
e.g. with the ``'de'`` language: e.g. with the ``'de'`` language:
* ``1000000`` becomes ``'1,0 Million'``. * ``1000000`` becomes ``'1,0 Million'``.
* ``1200000`` becomes ``'1,2 Million'``. * ``1200000`` becomes ``'1,2 Million'``.
* ``1200000000`` becomes ``'1,2 Milliarden'``. * ``1200000000`` becomes ``'1,2 Milliarden'``.
You can pass in either an integer or a string representation of an integer. You can pass in either an integer or a string representation of an integer.
@ -89,11 +89,11 @@ the passed in format string.
Examples (when 'today' is 17 Feb 2007): Examples (when 'today' is 17 Feb 2007):
* ``16 Feb 2007`` becomes ``yesterday``. * ``16 Feb 2007`` becomes ``yesterday``.
* ``17 Feb 2007`` becomes ``today``. * ``17 Feb 2007`` becomes ``today``.
* ``18 Feb 2007`` becomes ``tomorrow``. * ``18 Feb 2007`` becomes ``tomorrow``.
* Any other day is formatted according to given argument or the * Any other day is formatted according to given argument or the
:setting:`DATE_FORMAT` setting if no argument is given. :setting:`DATE_FORMAT` setting if no argument is given.
.. templatefilter:: naturaltime .. templatefilter:: naturaltime
@ -109,19 +109,19 @@ the return value will automatically use an appropriate phrase.
Examples (when 'now' is 17 Feb 2007 16:30:00): Examples (when 'now' is 17 Feb 2007 16:30:00):
* ``17 Feb 2007 16:30:00`` becomes ``now``. * ``17 Feb 2007 16:30:00`` becomes ``now``.
* ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``. * ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``.
* ``17 Feb 2007 16:29:00`` becomes ``a minute ago``. * ``17 Feb 2007 16:29:00`` becomes ``a minute ago``.
* ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``. * ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
* ``17 Feb 2007 15:30:29`` becomes ``an hour ago``. * ``17 Feb 2007 15:30:29`` becomes ``an hour ago``.
* ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``. * ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``.
* ``16 Feb 2007 13:31:29`` becomes ``1 day ago``. * ``16 Feb 2007 13:31:29`` becomes ``1 day ago``.
* ``17 Feb 2007 16:30:30`` becomes ``29 seconds from now``. * ``17 Feb 2007 16:30:30`` becomes ``29 seconds from now``.
* ``17 Feb 2007 16:31:00`` becomes ``a minute from now``. * ``17 Feb 2007 16:31:00`` becomes ``a minute from now``.
* ``17 Feb 2007 16:34:35`` becomes ``4 minutes from now``. * ``17 Feb 2007 16:34:35`` becomes ``4 minutes from now``.
* ``17 Feb 2007 16:30:29`` becomes ``an hour from now``. * ``17 Feb 2007 16:30:29`` becomes ``an hour from now``.
* ``17 Feb 2007 18:31:29`` becomes ``2 hours from now``. * ``17 Feb 2007 18:31:29`` becomes ``2 hours from now``.
* ``18 Feb 2007 16:31:29`` becomes ``1 day from now``. * ``18 Feb 2007 16:31:29`` becomes ``1 day from now``.
.. templatefilter:: ordinal .. templatefilter:: ordinal
@ -132,8 +132,8 @@ Converts an integer to its ordinal as a string.
Examples: Examples:
* ``1`` becomes ``1st``. * ``1`` becomes ``1st``.
* ``2`` becomes ``2nd``. * ``2`` becomes ``2nd``.
* ``3`` becomes ``3rd``. * ``3`` becomes ``3rd``.
You can pass in either an integer or a string representation of an integer. You can pass in either an integer or a string representation of an integer.

View File

@ -8,10 +8,10 @@ django.contrib.markup
Django provides template filters that implement the following markup Django provides template filters that implement the following markup
languages: languages:
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_ * ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ * ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_
* ``restructuredtext`` -- implements `reST (reStructured Text)`_ * ``restructuredtext`` -- implements `reST (reStructured Text)`_
-- requires `doc-utils`_ -- requires `doc-utils`_
In each case, the filter expects formatted markup as a string and In each case, the filter expects formatted markup as a string and
returns a string representing the marked-up text. For example, the returns a string representing the marked-up text. For example, the

View File

@ -23,20 +23,20 @@ class and corresponding :doc:`context processor </ref/templates/api>`.
To enable message functionality, do the following: To enable message functionality, do the following:
* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure * Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
it contains ``'django.contrib.messages.middleware.MessageMiddleware'``. it contains ``'django.contrib.messages.middleware.MessageMiddleware'``.
If you are using a :ref:`storage backend <message-storage-backends>` that If you are using a :ref:`storage backend <message-storage-backends>` that
relies on :doc:`sessions </topics/http/sessions>` (the default), relies on :doc:`sessions </topics/http/sessions>` (the default),
``'django.contrib.sessions.middleware.SessionMiddleware'`` must be ``'django.contrib.sessions.middleware.SessionMiddleware'`` must be
enabled and appear before ``MessageMiddleware`` in your enabled and appear before ``MessageMiddleware`` in your
:setting:`MIDDLEWARE_CLASSES`. :setting:`MIDDLEWARE_CLASSES`.
* Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure * Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure
it contains ``'django.contrib.messages.context_processors.messages'``. it contains ``'django.contrib.messages.context_processors.messages'``.
* Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS` * Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS`
setting setting
The default ``settings.py`` created by ``django-admin.py startproject`` has The default ``settings.py`` created by ``django-admin.py startproject`` has
``MessageMiddleware`` activated and the ``django.contrib.messages`` app ``MessageMiddleware`` activated and the ``django.contrib.messages`` app
@ -349,9 +349,9 @@ Default: ``'django.contrib.messages.storage.user_messages.FallbackStorage'``
Controls where Django stores message data. Valid values are: Controls where Django stores message data. Valid values are:
* ``'django.contrib.messages.storage.fallback.FallbackStorage'`` * ``'django.contrib.messages.storage.fallback.FallbackStorage'``
* ``'django.contrib.messages.storage.session.SessionStorage'`` * ``'django.contrib.messages.storage.session.SessionStorage'``
* ``'django.contrib.messages.storage.cookie.CookieStorage'`` * ``'django.contrib.messages.storage.cookie.CookieStorage'``
See `Storage backends`_ for more details. See `Storage backends`_ for more details.

View File

@ -13,11 +13,11 @@ Installation
To install the redirects app, follow these steps: To install the redirects app, follow these steps:
1. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS` 1. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS`
setting. setting.
2. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'`` 2. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'``
to your :setting:`MIDDLEWARE_CLASSES` setting. to your :setting:`MIDDLEWARE_CLASSES` setting.
3. Run the command :djadmin:`manage.py syncdb <syncdb>`. 3. Run the command :djadmin:`manage.py syncdb <syncdb>`.
How it works How it works
============ ============
@ -31,12 +31,12 @@ for the requested URL as a last resort. Specifically, it checks for a redirect
with the given ``old_path`` with a site ID that corresponds to the with the given ``old_path`` with a site ID that corresponds to the
:setting:`SITE_ID` setting. :setting:`SITE_ID` setting.
* If it finds a match, and ``new_path`` is not empty, it redirects to * If it finds a match, and ``new_path`` is not empty, it redirects to
``new_path``. ``new_path``.
* If it finds a match, and ``new_path`` is empty, it sends a 410 ("Gone") * If it finds a match, and ``new_path`` is empty, it sends a 410 ("Gone")
HTTP header and empty (content-less) response. HTTP header and empty (content-less) response.
* If it doesn't find a match, the request continues to be processed as * If it doesn't find a match, the request continues to be processed as
usual. usual.
The middleware only gets activated for 404s -- not for 500s or responses of any The middleware only gets activated for 404s -- not for 500s or responses of any
other status code. other status code.

View File

@ -31,15 +31,15 @@ Installation
To install the sitemap app, follow these steps: To install the sitemap app, follow these steps:
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS` 1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
setting. setting.
2. Make sure ``'django.template.loaders.app_directories.Loader'`` 2. Make sure ``'django.template.loaders.app_directories.Loader'``
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default, 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. so you'll only need to change this if you've changed that setting.
3. Make sure you've installed the 3. Make sure you've installed the
:mod:`sites framework <django.contrib.sites>`. :mod:`sites framework <django.contrib.sites>`.
(Note: The sitemap application doesn't install any database tables. The only (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 reason it needs to go into :setting:`INSTALLED_APPS` is so that the
@ -109,20 +109,20 @@ your sitemap class might look::
Note: Note:
* :attr:`~Sitemap.changefreq` and :attr:`~Sitemap.priority` are class * :attr:`~Sitemap.changefreq` and :attr:`~Sitemap.priority` are class
attributes corresponding to ``<changefreq>`` and ``<priority>`` elements, attributes corresponding to ``<changefreq>`` and ``<priority>`` elements,
respectively. They can be made callable as functions, as respectively. They can be made callable as functions, as
:attr:`~Sitemap.lastmod` was in the example. :attr:`~Sitemap.lastmod` was in the example.
* :attr:`~Sitemap.items()` is simply a method that returns a list of * :attr:`~Sitemap.items()` is simply a method that returns a list of
objects. The objects returned will get passed to any callable methods objects. The objects returned will get passed to any callable methods
corresponding to a sitemap property (:attr:`~Sitemap.location`, corresponding to a sitemap property (:attr:`~Sitemap.location`,
:attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and :attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and
:attr:`~Sitemap.priority`). :attr:`~Sitemap.priority`).
* :attr:`~Sitemap.lastmod` should return a Python ``datetime`` object. * :attr:`~Sitemap.lastmod` should return a Python ``datetime`` object.
* There is no :attr:`~Sitemap.location` method in this example, but you * There is no :attr:`~Sitemap.location` method in this example, but you
can provide it in order to specify the URL for your object. By default, can provide it in order to specify the URL for your object. By default,
:attr:`~Sitemap.location()` calls ``get_absolute_url()`` on each object :attr:`~Sitemap.location()` calls ``get_absolute_url()`` on each object
and returns the result. and returns the result.
Sitemap class reference Sitemap class reference
======================= =======================
@ -153,9 +153,9 @@ Sitemap class reference
In both cases, "absolute path" means a URL that doesn't include the In both cases, "absolute path" means a URL that doesn't include the
protocol or domain. Examples: protocol or domain. Examples:
* Good: :file:`'/foo/bar/'` * Good: :file:`'/foo/bar/'`
* Bad: :file:`'example.com/foo/bar/'` * Bad: :file:`'example.com/foo/bar/'`
* Bad: :file:`'http://example.com/foo/bar/'` * Bad: :file:`'http://example.com/foo/bar/'`
If :attr:`~Sitemap.location` isn't provided, the framework will call If :attr:`~Sitemap.location` isn't provided, the framework will call
the ``get_absolute_url()`` method on each object as returned by the ``get_absolute_url()`` method on each object as returned by
@ -185,13 +185,13 @@ Sitemap class reference
Possible values for :attr:`~Sitemap.changefreq`, whether you use a method or attribute, are: Possible values for :attr:`~Sitemap.changefreq`, whether you use a method or attribute, are:
* ``'always'`` * ``'always'``
* ``'hourly'`` * ``'hourly'``
* ``'daily'`` * ``'daily'``
* ``'weekly'`` * ``'weekly'``
* ``'monthly'`` * ``'monthly'``
* ``'yearly'`` * ``'yearly'``
* ``'never'`` * ``'never'``
.. method:: Sitemap.priority .. method:: Sitemap.priority
@ -272,10 +272,10 @@ The sitemap framework also has the ability to create a sitemap index that
references individual sitemap files, one per each section defined in your references individual sitemap files, one per each section defined in your
:data:`sitemaps` dictionary. The only differences in usage are: :data:`sitemaps` dictionary. The only differences in usage are:
* You use two views in your URLconf: :func:`django.contrib.sitemaps.views.index` * You use two views in your URLconf: :func:`django.contrib.sitemaps.views.index`
and :func:`django.contrib.sitemaps.views.sitemap`. and :func:`django.contrib.sitemaps.views.sitemap`.
* The :func:`django.contrib.sitemaps.views.sitemap` view should take a * The :func:`django.contrib.sitemaps.views.sitemap` view should take a
:data:`section` keyword argument. :data:`section` keyword argument.
Here's what the relevant URLconf lines would look like for the example above:: Here's what the relevant URLconf lines would look like for the example above::
@ -341,11 +341,11 @@ The variable :data:`urlset` is a list of URLs that should appear in the
sitemap. Each URL exposes attributes as defined in the sitemap. Each URL exposes attributes as defined in the
:class:`~django.contrib.sitemaps.Sitemap` class: :class:`~django.contrib.sitemaps.Sitemap` class:
- ``changefreq`` - ``changefreq``
- ``item`` - ``item``
- ``lastmod`` - ``lastmod``
- ``location`` - ``location``
- ``priority`` - ``priority``
.. versionadded:: 1.4 .. versionadded:: 1.4

View File

@ -70,24 +70,24 @@ that's represented by a :class:`~django.db.models.ManyToManyField` in the
This accomplishes several things quite nicely: This accomplishes several things quite nicely:
* It lets the site producers edit all content -- on both sites -- in a * It lets the site producers edit all content -- on both sites -- in a
single interface (the Django admin). single interface (the Django admin).
* It means the same story doesn't have to be published twice in the * It means the same story doesn't have to be published twice in the
database; it only has a single record in the database. database; it only has a single record in the database.
* It lets the site developers use the same Django view code for both sites. * It lets the site developers use the same Django view code for both sites.
The view code that displays a given story just checks to make sure the The view code that displays a given story just checks to make sure the
requested story is on the current site. It looks something like this:: requested story is on the current site. It looks something like this::
from django.conf import settings from django.conf import settings
def article_detail(request, article_id): def article_detail(request, article_id):
try: try:
a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID) a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID)
except Article.DoesNotExist: except Article.DoesNotExist:
raise Http404 raise Http404
# ... # ...
.. _ljworld.com: http://www.ljworld.com/ .. _ljworld.com: http://www.ljworld.com/
.. _lawrence.com: http://www.lawrence.com/ .. _lawrence.com: http://www.lawrence.com/

View File

@ -385,19 +385,19 @@ There are a few other helpers outside of the
:mod:`staticfiles <django.contrib.staticfiles>` app to work with static :mod:`staticfiles <django.contrib.staticfiles>` app to work with static
files: files:
- The :func:`django.core.context_processors.static` context processor - The :func:`django.core.context_processors.static` context processor
which adds :setting:`STATIC_URL` to every template context rendered which adds :setting:`STATIC_URL` to every template context rendered
with :class:`~django.template.RequestContext` contexts. with :class:`~django.template.RequestContext` contexts.
- The builtin template tag :ttag:`static` which takes a path and - The builtin template tag :ttag:`static` which takes a path and
urljoins it with the static prefix :setting:`STATIC_URL`. urljoins it with the static prefix :setting:`STATIC_URL`.
- The builtin template tag :ttag:`get_static_prefix` which populates a - The builtin template tag :ttag:`get_static_prefix` which populates a
template variable with the static prefix :setting:`STATIC_URL` to be template variable with the static prefix :setting:`STATIC_URL` to be
used as a variable or directly. used as a variable or directly.
- The similar template tag :ttag:`get_media_prefix` which works like - The similar template tag :ttag:`get_media_prefix` which works like
:ttag:`get_static_prefix` but uses :setting:`MEDIA_URL`. :ttag:`get_static_prefix` but uses :setting:`MEDIA_URL`.
.. _staticfiles-development-view: .. _staticfiles-development-view:

View File

@ -113,45 +113,45 @@ One thing is left to do. In an RSS feed, each ``<item>`` has a ``<title>``,
``<link>`` and ``<description>``. We need to tell the framework what data to put ``<link>`` and ``<description>``. We need to tell the framework what data to put
into those elements. into those elements.
* For the contents of ``<title>`` and ``<description>``, Django tries * For the contents of ``<title>`` and ``<description>``, Django tries
calling the methods ``item_title()`` and ``item_description()`` on calling the methods ``item_title()`` and ``item_description()`` on
the :class:`~django.contrib.syndication.views.Feed` class. They are passed the :class:`~django.contrib.syndication.views.Feed` class. They are passed
a single parameter, ``item``, which is the object itself. These are a single parameter, ``item``, which is the object itself. These are
optional; by default, the unicode representation of the object is used for optional; by default, the unicode representation of the object is used for
both. both.
If you want to do any special formatting for either the title or If you want to do any special formatting for either the title or
description, :doc:`Django templates </topics/templates>` can be used description, :doc:`Django templates </topics/templates>` can be used
instead. Their paths can be specified with the ``title_template`` and instead. Their paths can be specified with the ``title_template`` and
``description_template`` attributes on the ``description_template`` attributes on the
:class:`~django.contrib.syndication.views.Feed` class. The templates are :class:`~django.contrib.syndication.views.Feed` class. The templates are
rendered for each item and are passed two template context variables: rendered for each item and are passed two template context variables:
* ``{{ obj }}`` -- The current object (one of whichever objects you * ``{{ obj }}`` -- The current object (one of whichever objects you
returned in ``items()``). returned in ``items()``).
* ``{{ site }}`` -- A :class:`django.contrib.sites.models.Site` object * ``{{ site }}`` -- A :class:`django.contrib.sites.models.Site` object
representing the current site. This is useful for ``{{ site.domain representing the current site. This is useful for ``{{ site.domain
}}`` or ``{{ site.name }}``. If you do *not* have the Django sites }}`` or ``{{ site.name }}``. If you do *not* have the Django sites
framework installed, this will be set to a framework installed, this will be set to a
:class:`django.contrib.sites.models.RequestSite` object. See the :class:`django.contrib.sites.models.RequestSite` object. See the
:ref:`RequestSite section of the sites framework documentation :ref:`RequestSite section of the sites framework documentation
<requestsite-objects>` for more. <requestsite-objects>` for more.
See `a complex example`_ below that uses a description template. See `a complex example`_ below that uses a description template.
* To specify the contents of ``<link>``, you have two options. For each item * To specify the contents of ``<link>``, you have two options. For each item
in ``items()``, Django first tries calling the in ``items()``, Django first tries calling the
``item_link()`` method on the ``item_link()`` method on the
:class:`~django.contrib.syndication.views.Feed` class. In a similar way to :class:`~django.contrib.syndication.views.Feed` class. In a similar way to
the title and description, it is passed it a single parameter, the title and description, it is passed it a single parameter,
``item``. If that method doesn't exist, Django tries executing a ``item``. If that method doesn't exist, Django tries executing a
``get_absolute_url()`` method on that object. Both ``get_absolute_url()`` method on that object. Both
``get_absolute_url()`` and ``item_link()`` should return the ``get_absolute_url()`` and ``item_link()`` should return the
item's URL as a normal Python string. As with ``get_absolute_url()``, the item's URL as a normal Python string. As with ``get_absolute_url()``, the
result of ``item_link()`` will be included directly in the URL, so you result of ``item_link()`` will be included directly in the URL, so you
are responsible for doing all necessary URL quoting and conversion to are responsible for doing all necessary URL quoting and conversion to
ASCII inside the method itself. ASCII inside the method itself.
.. _chicagocrime.org: http://www.chicagocrime.org/ .. _chicagocrime.org: http://www.chicagocrime.org/
@ -170,8 +170,8 @@ items based on information in the feed's URL.
On chicagocrime.org, the police-beat feeds are accessible via URLs like this: On chicagocrime.org, the police-beat feeds are accessible via URLs like this:
* :file:`/beats/613/rss/` -- Returns recent crimes for beat 613. * :file:`/beats/613/rss/` -- Returns recent crimes for beat 613.
* :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424. * :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424.
These can be matched with a :doc:`URLconf </topics/http/urls>` line such as:: These can be matched with a :doc:`URLconf </topics/http/urls>` line such as::
@ -213,12 +213,12 @@ illustrates that they can be either strings *or* methods. For each of
``title``, ``link`` and ``description``, Django follows this ``title``, ``link`` and ``description``, Django follows this
algorithm: algorithm:
* First, it tries to call a method, passing the ``obj`` argument, where * First, it tries to call a method, passing the ``obj`` argument, where
``obj`` is the object returned by ``get_object()``. ``obj`` is the object returned by ``get_object()``.
* Failing that, it tries to call a method with no arguments. * Failing that, it tries to call a method with no arguments.
* Failing that, it uses the class attribute. * Failing that, it uses the class attribute.
Also note that ``items()`` also follows the same algorithm -- first, it Also note that ``items()`` also follows the same algorithm -- first, it
tries ``items(obj)``, then ``items()``, then finally an ``items`` tries ``items(obj)``, then ``items()``, then finally an ``items``
@ -252,9 +252,9 @@ Note that you set ``feed_type`` to a class object, not an instance.
Currently available feed types are: Currently available feed types are:
* :class:`django.utils.feedgenerator.Rss201rev2Feed` (RSS 2.01. Default.) * :class:`django.utils.feedgenerator.Rss201rev2Feed` (RSS 2.01. Default.)
* :class:`django.utils.feedgenerator.RssUserland091Feed` (RSS 0.91.) * :class:`django.utils.feedgenerator.RssUserland091Feed` (RSS 0.91.)
* :class:`django.utils.feedgenerator.Atom1Feed` (Atom 1.0.) * :class:`django.utils.feedgenerator.Atom1Feed` (Atom 1.0.)
Enclosures Enclosures
---------- ----------
@ -788,13 +788,13 @@ also create custom feed generator subclasses for use with the ``feed_type``
The :mod:`~django.utils.feedgenerator` module contains a base class: The :mod:`~django.utils.feedgenerator` module contains a base class:
* :class:`django.utils.feedgenerator.SyndicationFeed` * :class:`django.utils.feedgenerator.SyndicationFeed`
and several subclasses: and several subclasses:
* :class:`django.utils.feedgenerator.RssUserland091Feed` * :class:`django.utils.feedgenerator.RssUserland091Feed`
* :class:`django.utils.feedgenerator.Rss201rev2Feed` * :class:`django.utils.feedgenerator.Rss201rev2Feed`
* :class:`django.utils.feedgenerator.Atom1Feed` * :class:`django.utils.feedgenerator.Atom1Feed`
Each of these three classes knows how to render a certain type of feed as XML. Each of these three classes knows how to render a certain type of feed as XML.
They share this interface: They share this interface:
@ -803,22 +803,22 @@ They share this interface:
Initialize the feed with the given dictionary of metadata, which applies to Initialize the feed with the given dictionary of metadata, which applies to
the entire feed. Required keyword arguments are: the entire feed. Required keyword arguments are:
* ``title`` * ``title``
* ``link`` * ``link``
* ``description`` * ``description``
There's also a bunch of other optional keywords: There's also a bunch of other optional keywords:
* ``language`` * ``language``
* ``author_email`` * ``author_email``
* ``author_name`` * ``author_name``
* ``author_link`` * ``author_link``
* ``subtitle`` * ``subtitle``
* ``categories`` * ``categories``
* ``feed_url`` * ``feed_url``
* ``feed_copyright`` * ``feed_copyright``
* ``feed_guid`` * ``feed_guid``
* ``ttl`` * ``ttl``
Any extra keyword arguments you pass to ``__init__`` will be stored in Any extra keyword arguments you pass to ``__init__`` will be stored in
``self.feed`` for use with `custom feed generators`_. ``self.feed`` for use with `custom feed generators`_.
@ -831,31 +831,31 @@ They share this interface:
Required keyword arguments are: Required keyword arguments are:
* ``title`` * ``title``
* ``link`` * ``link``
* ``description`` * ``description``
Optional keyword arguments are: Optional keyword arguments are:
* ``author_email`` * ``author_email``
* ``author_name`` * ``author_name``
* ``author_link`` * ``author_link``
* ``pubdate`` * ``pubdate``
* ``comments`` * ``comments``
* ``unique_id`` * ``unique_id``
* ``enclosure`` * ``enclosure``
* ``categories`` * ``categories``
* ``item_copyright`` * ``item_copyright``
* ``ttl`` * ``ttl``
Extra keyword arguments will be stored for `custom feed generators`_. Extra keyword arguments will be stored for `custom feed generators`_.
All parameters, if given, should be Unicode objects, except: All parameters, if given, should be Unicode objects, except:
* ``pubdate`` should be a Python :class:`~datetime.datetime` object. * ``pubdate`` should be a Python :class:`~datetime.datetime` object.
* ``enclosure`` should be an instance of * ``enclosure`` should be an instance of
:class:`django.utils.feedgenerator.Enclosure`. :class:`django.utils.feedgenerator.Enclosure`.
* ``categories`` should be a sequence of Unicode objects. * ``categories`` should be a sequence of Unicode objects.
:meth:`.SyndicationFeed.write` :meth:`.SyndicationFeed.write`
Outputs the feed in the given encoding to outfile, which is a file-like object. Outputs the feed in the given encoding to outfile, which is a file-like object.

View File

@ -36,21 +36,21 @@ Usage::
The ``{% lorem %}`` tag can be used with zero, one, two or three arguments. The ``{% lorem %}`` tag can be used with zero, one, two or three arguments.
The arguments are: The arguments are:
=========== ============================================================= =========== =============================================================
Argument Description Argument Description
=========== ============================================================= =========== =============================================================
``count`` A number (or variable) containing the number of paragraphs or ``count`` A number (or variable) containing the number of paragraphs or
words to generate (default is 1). words to generate (default is 1).
``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b`` ``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b``
for plain-text paragraph blocks (default is ``b``). for plain-text paragraph blocks (default is ``b``).
``random`` The word ``random``, which if given, does not use the common ``random`` The word ``random``, which if given, does not use the common
paragraph ("Lorem ipsum dolor sit amet...") when generating paragraph ("Lorem ipsum dolor sit amet...") when generating
text. text.
=========== ============================================================= =========== =============================================================
Examples: Examples:
* ``{% lorem %}`` will output the common "lorem ipsum" paragraph. * ``{% lorem %}`` will output the common "lorem ipsum" paragraph.
* ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph * ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph
and two random paragraphs each wrapped in HTML ``<p>`` tags. and two random paragraphs each wrapped in HTML ``<p>`` tags.
* ``{% lorem 2 w random %}`` will output two random Latin words. * ``{% lorem 2 w random %}`` will output two random Latin words.

View File

@ -257,10 +257,10 @@ Refer to the :doc:`settings documentation </ref/settings>`.
Connection settings are used in this order: Connection settings are used in this order:
1. :setting:`OPTIONS`. 1. :setting:`OPTIONS`.
2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`, 2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
:setting:`HOST`, :setting:`PORT` :setting:`HOST`, :setting:`PORT`
3. MySQL option files. 3. MySQL option files.
In other words, if you set the name of the database in :setting:`OPTIONS`, In other words, if you set the name of the database in :setting:`OPTIONS`,
this will take precedence over :setting:`NAME`, which would override this will take precedence over :setting:`NAME`, which would override
@ -304,25 +304,25 @@ default storage engine to the desired engine.
If you're using a hosting service and can't change your server's default If you're using a hosting service and can't change your server's default
storage engine, you have a couple of options. storage engine, you have a couple of options.
* After the tables are created, execute an ``ALTER TABLE`` statement to * After the tables are created, execute an ``ALTER TABLE`` statement to
convert a table to a new storage engine (such as InnoDB):: convert a table to a new storage engine (such as InnoDB)::
ALTER TABLE <tablename> ENGINE=INNODB; ALTER TABLE <tablename> ENGINE=INNODB;
This can be tedious if you have a lot of tables. This can be tedious if you have a lot of tables.
* Another option is to use the ``init_command`` option for MySQLdb prior to * Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables:: creating your tables::
'OPTIONS': { 'OPTIONS': {
'init_command': 'SET storage_engine=INNODB', 'init_command': 'SET storage_engine=INNODB',
} }
This sets the default storage engine upon connecting to the database. This sets the default storage engine upon connecting to the database.
After your tables have been created, you should remove this option. After your tables have been created, you should remove this option.
* Another method for changing the storage engine is described in * Another method for changing the storage engine is described in
AlterModelOnSyncDB_. AlterModelOnSyncDB_.
.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB .. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB
@ -422,13 +422,13 @@ SQLite 3.3.6 or newer strongly recommended
Versions of SQLite 3.3.5 and older contains the following bugs: Versions of SQLite 3.3.5 and older contains the following bugs:
* A bug when `handling`_ ``ORDER BY`` parameters. This can cause problems when * A bug when `handling`_ ``ORDER BY`` parameters. This can cause problems when
you use the ``select`` parameter for the ``extra()`` QuerySet method. The bug you use the ``select`` parameter for the ``extra()`` QuerySet method. The bug
can be identified by the error message ``OperationalError: ORDER BY terms can be identified by the error message ``OperationalError: ORDER BY terms
must not be non-integer constants``. must not be non-integer constants``.
* A bug when handling `aggregation`_ together with DateFields and * A bug when handling `aggregation`_ together with DateFields and
DecimalFields. DecimalFields.
.. _handling: http://www.sqlite.org/cvstrac/tktview?tn=1768 .. _handling: http://www.sqlite.org/cvstrac/tktview?tn=1768
.. _aggregation: http://code.djangoproject.com/ticket/10031 .. _aggregation: http://code.djangoproject.com/ticket/10031
@ -507,24 +507,24 @@ is locked`` error.
If you're getting this error, you can solve it by: If you're getting this error, you can solve it by:
* Switching to another database backend. At a certain point SQLite becomes * Switching to another database backend. At a certain point SQLite becomes
too "lite" for real-world applications, and these sorts of concurrency too "lite" for real-world applications, and these sorts of concurrency
errors indicate you've reached that point. errors indicate you've reached that point.
* Rewriting your code to reduce concurrency and ensure that database * Rewriting your code to reduce concurrency and ensure that database
transactions are short-lived. transactions are short-lived.
* Increase the default timeout value by setting the ``timeout`` database * Increase the default timeout value by setting the ``timeout`` database
option option:: option option::
'OPTIONS': { 'OPTIONS': {
# ... # ...
'timeout': 20, 'timeout': 20,
# ... # ...
} }
This will simply make SQLite wait a bit longer before throwing "database This will simply make SQLite wait a bit longer before throwing "database
is locked" errors; it won't really do anything to solve them. is locked" errors; it won't really do anything to solve them.
``QuerySet.select_for_update()`` not supported ``QuerySet.select_for_update()`` not supported
---------------------------------------------- ----------------------------------------------
@ -567,19 +567,19 @@ required.
In order for the ``python manage.py syncdb`` command to work, your Oracle In order for the ``python manage.py syncdb`` command to work, your Oracle
database user must have privileges to run the following commands: database user must have privileges to run the following commands:
* CREATE TABLE * CREATE TABLE
* CREATE SEQUENCE * CREATE SEQUENCE
* CREATE PROCEDURE * CREATE PROCEDURE
* CREATE TRIGGER * CREATE TRIGGER
To run Django's test suite, the user needs these *additional* privileges: To run Django's test suite, the user needs these *additional* privileges:
* CREATE USER * CREATE USER
* DROP USER * DROP USER
* CREATE TABLESPACE * CREATE TABLESPACE
* DROP TABLESPACE * DROP TABLESPACE
* CONNECT WITH ADMIN OPTION * CONNECT WITH ADMIN OPTION
* RESOURCE WITH ADMIN OPTION * RESOURCE WITH ADMIN OPTION
Connecting to the database Connecting to the database
-------------------------- --------------------------
@ -721,16 +721,16 @@ assumption.
The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes
some limitations on the usage of such LOB columns in general: some limitations on the usage of such LOB columns in general:
* LOB columns may not be used as primary keys. * LOB columns may not be used as primary keys.
* LOB columns may not be used in indexes. * LOB columns may not be used in indexes.
* LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that * LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that
attempting to use the ``QuerySet.distinct`` method on a model that attempting to use the ``QuerySet.distinct`` method on a model that
includes ``TextField`` columns will result in an error when run against includes ``TextField`` columns will result in an error when run against
Oracle. As a workaround, use the ``QuerySet.defer`` method in conjunction Oracle. As a workaround, use the ``QuerySet.defer`` method in conjunction
with ``distinct()`` to prevent ``TextField`` columns from being included in with ``distinct()`` to prevent ``TextField`` columns from being included in
the ``SELECT DISTINCT`` list. the ``SELECT DISTINCT`` list.
.. _third-party-notes: .. _third-party-notes:

View File

@ -9,10 +9,10 @@ In addition, ``manage.py`` is automatically created in each Django project.
``manage.py`` is a thin wrapper around ``django-admin.py`` that takes care of ``manage.py`` is a thin wrapper around ``django-admin.py`` that takes care of
two things for you before delegating to ``django-admin.py``: two things for you before delegating to ``django-admin.py``:
* It puts your project's package on ``sys.path``. * It puts your project's package on ``sys.path``.
* It sets the :envvar:`DJANGO_SETTINGS_MODULE` environment variable so that * It sets the :envvar:`DJANGO_SETTINGS_MODULE` environment variable so that
it points to your project's ``settings.py`` file. it points to your project's ``settings.py`` file.
The ``django-admin.py`` script should be on your system path if you installed The ``django-admin.py`` script should be on your system path if you installed
Django via its ``setup.py`` utility. If it's not on your path, you can find it Django via its ``setup.py`` utility. If it's not on your path, you can find it
@ -128,9 +128,9 @@ Runs the command-line client for the database engine specified in your
``ENGINE`` setting, with the connection parameters specified in your ``ENGINE`` setting, with the connection parameters specified in your
:setting:`USER`, :setting:`PASSWORD`, etc., settings. :setting:`USER`, :setting:`PASSWORD`, etc., settings.
* For PostgreSQL, this runs the ``psql`` command-line client. * For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` command-line client. * For MySQL, this runs the ``mysql`` command-line client.
* For SQLite, this runs the ``sqlite3`` command-line client. * For SQLite, this runs the ``sqlite3`` command-line client.
This command assumes the programs are on your ``PATH`` so that a simple call to This command assumes the programs are on your ``PATH`` so that a simple call to
the program name (``psql``, ``mysql``, ``sqlite3``) will find the program in the program name (``psql``, ``mysql``, ``sqlite3``) will find the program in
@ -257,19 +257,19 @@ As you might expect, the created models will have an attribute for every field
in the table. Note that ``inspectdb`` has a few special cases in its field-name in the table. Note that ``inspectdb`` has a few special cases in its field-name
output: output:
* If ``inspectdb`` cannot map a column's type to a model field type, it'll * If ``inspectdb`` cannot map a column's type to a model field type, it'll
use ``TextField`` and will insert the Python comment use ``TextField`` and will insert the Python comment
``'This field type is a guess.'`` next to the field in the generated ``'This field type is a guess.'`` next to the field in the generated
model. model.
* If the database column name is a Python reserved word (such as * If the database column name is a Python reserved word (such as
``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append ``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append
``'_field'`` to the attribute name. For example, if a table has a column ``'_field'`` to the attribute name. For example, if a table has a column
``'for'``, the generated model will have a field ``'for_field'``, with ``'for'``, the generated model will have a field ``'for_field'``, with
the ``db_column`` attribute set to ``'for'``. ``inspectdb`` will insert the ``db_column`` attribute set to ``'for'``. ``inspectdb`` will insert
the Python comment the Python comment
``'Field renamed because it was a Python reserved word.'`` next to the ``'Field renamed because it was a Python reserved word.'`` next to the
field. field.
This feature is meant as a shortcut, not as definitive model generation. After This feature is meant as a shortcut, not as definitive model generation. After
you run it, you'll want to look over the generated models yourself to make you run it, you'll want to look over the generated models yourself to make
@ -309,9 +309,9 @@ fixture can be distributed over multiple directories, in multiple applications.
Django will search in three locations for fixtures: Django will search in three locations for fixtures:
1. In the ``fixtures`` directory of every installed application 1. In the ``fixtures`` directory of every installed application
2. In any directory named in the :setting:`FIXTURE_DIRS` setting 2. In any directory named in the :setting:`FIXTURE_DIRS` setting
3. In the literal path named by the fixture 3. In the literal path named by the fixture
Django will load any and all fixtures it finds in these locations that match Django will load any and all fixtures it finds in these locations that match
the provided fixture names. the provided fixture names.
@ -438,8 +438,8 @@ Example usage::
Use the ``--domain`` or ``-d`` option to change the domain of the messages files. Use the ``--domain`` or ``-d`` option to change the domain of the messages files.
Currently supported: Currently supported:
* ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default) * ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default)
* ``djangojs`` for ``*.js`` files * ``djangojs`` for ``*.js`` files
.. django-admin-option:: --symlinks .. django-admin-option:: --symlinks
@ -984,25 +984,25 @@ For example, this command::
...would perform the following steps: ...would perform the following steps:
1. Create a test database, as described in :doc:`/topics/testing`. 1. Create a test database, as described in :doc:`/topics/testing`.
2. Populate the test database with fixture data from the given fixtures. 2. Populate the test database with fixture data from the given fixtures.
(For more on fixtures, see the documentation for ``loaddata`` above.) (For more on fixtures, see the documentation for ``loaddata`` above.)
3. Runs the Django development server (as in ``runserver``), pointed at 3. Runs the Django development server (as in ``runserver``), pointed at
this newly created test database instead of your production database. this newly created test database instead of your production database.
This is useful in a number of ways: This is useful in a number of ways:
* When you're writing :doc:`unit tests </topics/testing>` of how your views * When you're writing :doc:`unit tests </topics/testing>` of how your views
act with certain fixture data, you can use ``testserver`` to interact with act with certain fixture data, you can use ``testserver`` to interact with
the views in a Web browser, manually. the views in a Web browser, manually.
* Let's say you're developing your Django application and have a "pristine" * Let's say you're developing your Django application and have a "pristine"
copy of a database that you'd like to interact with. You can dump your copy of a database that you'd like to interact with. You can dump your
database to a fixture (using the ``dumpdata`` command, explained above), database to a fixture (using the ``dumpdata`` command, explained above),
then use ``testserver`` to run your Web application with that data. With then use ``testserver`` to run your Web application with that data. With
this arrangement, you have the flexibility of messing up your data this arrangement, you have the flexibility of messing up your data
in any way, knowing that whatever data changes you're making are only in any way, knowing that whatever data changes you're making are only
being made to a test database. being made to a test database.
Note that this server does *not* automatically detect changes to your Python Note that this server does *not* automatically detect changes to your Python
source code (as ``runserver`` does). It does, however, detect changes to source code (as ``runserver`` does). It does, however, detect changes to
@ -1197,10 +1197,10 @@ Example usage::
Use ``--verbosity`` to specify the amount of notification and debug information Use ``--verbosity`` to specify the amount of notification and debug information
that ``django-admin.py`` should print to the console. that ``django-admin.py`` should print to the console.
* ``0`` means no output. * ``0`` means no output.
* ``1`` means normal output (default). * ``1`` means normal output (default).
* ``2`` means verbose output. * ``2`` means verbose output.
* ``3`` means *very* verbose output. * ``3`` means *very* verbose output.
Common options Common options
============== ==============
@ -1259,13 +1259,13 @@ another program.
The colors used for syntax highlighting can be customized. Django The colors used for syntax highlighting can be customized. Django
ships with three color palettes: ships with three color palettes:
* ``dark``, suited to terminals that show white text on a black * ``dark``, suited to terminals that show white text on a black
background. This is the default palette. background. This is the default palette.
* ``light``, suited to terminals that show black text on a white * ``light``, suited to terminals that show black text on a white
background. background.
* ``nocolor``, which disables syntax highlighting. * ``nocolor``, which disables syntax highlighting.
You select a palette by setting a ``DJANGO_COLORS`` environment You select a palette by setting a ``DJANGO_COLORS`` environment
variable to specify the palette you want to use. For example, to variable to specify the palette you want to use. For example, to
@ -1277,47 +1277,47 @@ would run the following at a command prompt::
You can also customize the colors that are used. Django specifies a You can also customize the colors that are used. Django specifies a
number of roles in which color is used: number of roles in which color is used:
* ``error`` - A major error. * ``error`` - A major error.
* ``notice`` - A minor error. * ``notice`` - A minor error.
* ``sql_field`` - The name of a model field in SQL. * ``sql_field`` - The name of a model field in SQL.
* ``sql_coltype`` - The type of a model field in SQL. * ``sql_coltype`` - The type of a model field in SQL.
* ``sql_keyword`` - A SQL keyword. * ``sql_keyword`` - A SQL keyword.
* ``sql_table`` - The name of a model in SQL. * ``sql_table`` - The name of a model in SQL.
* ``http_info`` - A 1XX HTTP Informational server response. * ``http_info`` - A 1XX HTTP Informational server response.
* ``http_success`` - A 2XX HTTP Success server response. * ``http_success`` - A 2XX HTTP Success server response.
* ``http_not_modified`` - A 304 HTTP Not Modified server response. * ``http_not_modified`` - A 304 HTTP Not Modified server response.
* ``http_redirect`` - A 3XX HTTP Redirect server response other than 304. * ``http_redirect`` - A 3XX HTTP Redirect server response other than 304.
* ``http_not_found`` - A 404 HTTP Not Found server response. * ``http_not_found`` - A 404 HTTP Not Found server response.
* ``http_bad_request`` - A 4XX HTTP Bad Request server response other than 404. * ``http_bad_request`` - A 4XX HTTP Bad Request server response other than 404.
* ``http_server_error`` - A 5XX HTTP Server Error response. * ``http_server_error`` - A 5XX HTTP Server Error response.
Each of these roles can be assigned a specific foreground and Each of these roles can be assigned a specific foreground and
background color, from the following list: background color, from the following list:
* ``black`` * ``black``
* ``red`` * ``red``
* ``green`` * ``green``
* ``yellow`` * ``yellow``
* ``blue`` * ``blue``
* ``magenta`` * ``magenta``
* ``cyan`` * ``cyan``
* ``white`` * ``white``
Each of these colors can then be modified by using the following Each of these colors can then be modified by using the following
display options: display options:
* ``bold`` * ``bold``
* ``underscore`` * ``underscore``
* ``blink`` * ``blink``
* ``reverse`` * ``reverse``
* ``conceal`` * ``conceal``
A color specification follows one of the following patterns: A color specification follows one of the following patterns:
* ``role=fg`` * ``role=fg``
* ``role=fg/bg`` * ``role=fg/bg``
* ``role=fg,option,option`` * ``role=fg,option,option``
* ``role=fg/bg,option,option`` * ``role=fg/bg,option,option``
where ``role`` is the name of a valid color role, ``fg`` is the where ``role`` is the name of a valid color role, ``fg`` is the
foreground color, ``bg`` is the background color and each ``option`` foreground color, ``bg`` is the background color and each ``option``
@ -1348,10 +1348,10 @@ script, which lives in ``extras/django_bash_completion`` in the Django
distribution. It enables tab-completion of ``django-admin.py`` and distribution. It enables tab-completion of ``django-admin.py`` and
``manage.py`` commands, so you can, for instance... ``manage.py`` commands, so you can, for instance...
* Type ``django-admin.py``. * Type ``django-admin.py``.
* Press [TAB] to see all available options. * Press [TAB] to see all available options.
* Type ``sql``, then [TAB], to see all available options whose names start * Type ``sql``, then [TAB], to see all available options whose names start
with ``sql``. with ``sql``.
See :doc:`/howto/custom-management-commands` for how to add customized actions. See :doc:`/howto/custom-management-commands` for how to add customized actions.

View File

@ -84,15 +84,15 @@ FieldError
The :exc:`FieldError` exception is raised when there is a problem with a The :exc:`FieldError` exception is raised when there is a problem with a
model field. This can happen for several reasons: model field. This can happen for several reasons:
- A field in a model clashes with a field of the same name from an - A field in a model clashes with a field of the same name from an
abstract base class abstract base class
- An infinite loop is caused by ordering - An infinite loop is caused by ordering
- A keyword cannot be parsed from the filter parameters - A keyword cannot be parsed from the filter parameters
- A field cannot be determined from a keyword in the query - A field cannot be determined from a keyword in the query
parameters parameters
- A join is not permitted on the specified field - A join is not permitted on the specified field
- A field name is invalid - A field name is invalid
- A query contains invalid order_by arguments - A query contains invalid order_by arguments
ValidationError ValidationError
--------------- ---------------

View File

@ -19,11 +19,11 @@ Bound and unbound forms
A :class:`Form` instance is either **bound** to a set of data, or **unbound**. A :class:`Form` instance is either **bound** to a set of data, or **unbound**.
* If it's **bound** to a set of data, it's capable of validating that data * If it's **bound** to a set of data, it's capable of validating that data
and rendering the form as HTML with the data displayed in the HTML. and rendering the form as HTML with the data displayed in the HTML.
* If it's **unbound**, it cannot do validation (because there's no data to * 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. validate!), but it can still render the blank form as HTML.
.. class:: Form .. class:: Form
@ -292,29 +292,29 @@ include ``checked="checked"`` if appropriate::
This default output is a two-column HTML table, with a ``<tr>`` for each field. This default output is a two-column HTML table, with a ``<tr>`` for each field.
Notice the following: Notice the following:
* For flexibility, the output does *not* include the ``<table>`` and * For flexibility, the output does *not* include the ``<table>`` and
``</table>`` tags, nor does it include the ``<form>`` and ``</form>`` ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
tags or an ``<input type="submit">`` tag. It's your job to do that. tags or an ``<input type="submit">`` tag. It's your job to do that.
* Each field type has a default HTML representation. ``CharField`` and * Each field type has a default HTML representation. ``CharField`` and
``EmailField`` are represented by an ``<input type="text">``. ``EmailField`` are represented by an ``<input type="text">``.
``BooleanField`` is represented by an ``<input type="checkbox">``. Note ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
these are merely sensible defaults; you can specify which HTML to use for these are merely sensible defaults; you can specify which HTML to use for
a given field by using widgets, which we'll explain shortly. a given field by using widgets, which we'll explain shortly.
* The HTML ``name`` for each tag is taken directly from its attribute name * The HTML ``name`` for each tag is taken directly from its attribute name
in the ``ContactForm`` class. in the ``ContactForm`` class.
* The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
``'Cc myself:'`` is generated from the field name by converting all ``'Cc myself:'`` is generated from the field name by converting all
underscores to spaces and upper-casing the first letter. Again, note underscores to spaces and upper-casing the first letter. Again, note
these are merely sensible defaults; you can also specify labels manually. these are merely sensible defaults; you can also specify labels manually.
* Each text label is surrounded in an HTML ``<label>`` tag, which points * Each text label is surrounded in an HTML ``<label>`` tag, which points
to the appropriate form field via its ``id``. Its ``id``, in turn, is to the appropriate form field via its ``id``. Its ``id``, in turn, is
generated by prepending ``'id_'`` to the field name. The ``id`` generated by prepending ``'id_'`` to the field name. The ``id``
attributes and ``<label>`` tags are included in the output by default, to attributes and ``<label>`` tags are included in the output by default, to
follow best practices, but you can change that behavior. follow best practices, but you can change that behavior.
Although ``<table>`` output is the default output style when you ``print`` a Although ``<table>`` output is the default output style when you ``print`` a
form, other output styles are available. Each style is available as a method on form, other output styles are available. Each style is available as a method on

View File

@ -302,13 +302,13 @@ For each field, we describe the default widget used if you don't specify
the field has ``required=True``. the field has ``required=True``.
* Error message keys: ``required`` * Error message keys: ``required``
.. note:: .. note::
Since all ``Field`` subclasses have ``required=True`` by default, the Since all ``Field`` subclasses have ``required=True`` by default, the
validation condition here is important. If you want to include a boolean validation condition here is important. If you want to include a boolean
in your form that can be either ``True`` or ``False`` (e.g. a checked or in your form that can be either ``True`` or ``False`` (e.g. a checked or
unchecked checkbox), you must remember to pass in ``required=False`` when unchecked checkbox), you must remember to pass in ``required=False`` when
creating the ``BooleanField``. creating the ``BooleanField``.
``CharField`` ``CharField``
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -322,10 +322,10 @@ For each field, we describe the default widget used if you don't specify
Otherwise, all inputs are valid. Otherwise, all inputs are valid.
* Error message keys: ``required``, ``max_length``, ``min_length`` * Error message keys: ``required``, ``max_length``, ``min_length``
Has two optional arguments for validation: Has two optional arguments for validation:
.. attribute:: CharField.max_length .. attribute:: max_length
.. attribute:: CharField.min_length .. attribute:: min_length
If provided, these arguments ensure that the string is at most or at least If provided, these arguments ensure that the string is at most or at least
the given length. the given length.
@ -341,25 +341,25 @@ Has two optional arguments for validation:
* Validates that the given value exists in the list of choices. * Validates that the given value exists in the list of choices.
* Error message keys: ``required``, ``invalid_choice`` * Error message keys: ``required``, ``invalid_choice``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice. replaced with the selected choice.
Takes one extra required argument: Takes one extra required argument:
.. attribute:: ChoiceField.choices .. attribute:: choices
An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this
field. This argument accepts the same formats as the ``choices`` argument field. This argument accepts the same formats as the ``choices`` argument
to a model field. See the :ref:`model field reference documentation on to a model field. See the :ref:`model field reference documentation on
choices <field-choices>` for more details. choices <field-choices>` for more details.
``TypedChoiceField`` ``TypedChoiceField``
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
.. class:: TypedChoiceField(**kwargs) .. class:: TypedChoiceField(**kwargs)
Just like a :class:`ChoiceField`, except :class:`TypedChoiceField` takes two Just like a :class:`ChoiceField`, except :class:`TypedChoiceField` takes two
extra arguments, ``coerce`` and ``empty_value``. extra arguments, ``coerce`` and ``empty_value``.
* Default widget: ``Select`` * Default widget: ``Select``
* Empty value: Whatever you've given as ``empty_value`` * Empty value: Whatever you've given as ``empty_value``
@ -368,20 +368,20 @@ extra arguments, ``coerce`` and ``empty_value``.
coerced. coerced.
* Error message keys: ``required``, ``invalid_choice`` * Error message keys: ``required``, ``invalid_choice``
Takes extra arguments: Takes extra arguments:
.. attribute:: TypedChoiceField.coerce .. attribute:: coerce
A function that takes one argument and returns a coerced value. Examples A function that takes one argument and returns a coerced value. Examples
include the built-in ``int``, ``float``, ``bool`` and other types. Defaults include the built-in ``int``, ``float``, ``bool`` and other types. Defaults
to an identity function. to an identity function.
.. attribute:: TypedChoiceField.empty_value .. attribute:: empty_value
The value to use to represent "empty." Defaults to the empty string; The value to use to represent "empty." Defaults to the empty string;
``None`` is another common choice here. Note that this value will not be ``None`` is another common choice here. Note that this value will not be
coerced by the function given in the ``coerce`` argument, so choose it coerced by the function given in the ``coerce`` argument, so choose it
accordingly. accordingly.
``DateField`` ``DateField``
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -395,20 +395,20 @@ Takes extra arguments:
``datetime.datetime`` or string formatted in a particular date format. ``datetime.datetime`` or string formatted in a particular date format.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Takes one optional argument: Takes one optional argument:
.. attribute:: DateField.input_formats .. attribute:: input_formats
A list of formats used to attempt to convert a string to a valid A list of formats used to attempt to convert a string to a valid
``datetime.date`` object. ``datetime.date`` object.
If no ``input_formats`` argument is provided, the default input formats are:: If no ``input_formats`` argument is provided, the default input formats are::
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006' '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006' '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
'%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006' '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006' '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
``DateTimeField`` ``DateTimeField``
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
@ -422,24 +422,24 @@ If no ``input_formats`` argument is provided, the default input formats are::
``datetime.date`` or string formatted in a particular datetime format. ``datetime.date`` or string formatted in a particular datetime format.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Takes one optional argument: Takes one optional argument:
.. attribute:: DateTimeField.input_formats .. attribute:: input_formats
A list of formats used to attempt to convert a string to a valid A list of formats used to attempt to convert a string to a valid
``datetime.datetime`` object. ``datetime.datetime`` object.
If no ``input_formats`` argument is provided, the default input formats are:: If no ``input_formats`` argument is provided, the default input formats are::
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
'%Y-%m-%d %H:%M', # '2006-10-25 14:30' '%Y-%m-%d %H:%M', # '2006-10-25 14:30'
'%Y-%m-%d', # '2006-10-25' '%Y-%m-%d', # '2006-10-25'
'%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59'
'%m/%d/%Y %H:%M', # '10/25/2006 14:30' '%m/%d/%Y %H:%M', # '10/25/2006 14:30'
'%m/%d/%Y', # '10/25/2006' '%m/%d/%Y', # '10/25/2006'
'%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59'
'%m/%d/%y %H:%M', # '10/25/06 14:30' '%m/%d/%y %H:%M', # '10/25/06 14:30'
'%m/%d/%y', # '10/25/06' '%m/%d/%y', # '10/25/06'
``DecimalField`` ``DecimalField``
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -455,26 +455,26 @@ If no ``input_formats`` argument is provided, the default input formats are::
``min_value``, ``max_digits``, ``max_decimal_places``, ``min_value``, ``max_digits``, ``max_decimal_places``,
``max_whole_digits`` ``max_whole_digits``
The ``max_value`` and ``min_value`` error messages may contain The ``max_value`` and ``min_value`` error messages may contain
``%(limit_value)s``, which will be substituted by the appropriate limit. ``%(limit_value)s``, which will be substituted by the appropriate limit.
Takes four optional arguments: Takes four optional arguments:
.. attribute:: DecimalField.max_value .. attribute:: max_value
.. attribute:: DecimalField.min_value .. attribute:: min_value
These control the range of values permitted in the field, and should be These control the range of values permitted in the field, and should be
given as ``decimal.Decimal`` values. given as ``decimal.Decimal`` values.
.. attribute:: DecimalField.max_digits .. attribute:: max_digits
The maximum number of digits (those before the decimal point plus those The maximum number of digits (those before the decimal point plus those
after the decimal point, with leading zeros stripped) permitted in the after the decimal point, with leading zeros stripped) permitted in the
value. value.
.. attribute:: DecimalField.decimal_places .. attribute:: decimal_places
The maximum number of decimal places permitted. The maximum number of decimal places permitted.
``EmailField`` ``EmailField``
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -488,9 +488,9 @@ Takes four optional arguments:
moderately complex regular expression. moderately complex regular expression.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Has two optional arguments for validation, ``max_length`` and ``min_length``. Has two optional arguments for validation, ``max_length`` and ``min_length``.
If provided, these arguments ensure that the string is at most or at least the If provided, these arguments ensure that the string is at most or at least the
given length. given length.
.. versionchanged:: 1.2 .. versionchanged:: 1.2
The EmailField previously did not recognize email addresses as valid that The EmailField previously did not recognize email addresses as valid that
@ -510,20 +510,20 @@ given length.
* Error message keys: ``required``, ``invalid``, ``missing``, ``empty``, * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
``max_length`` ``max_length``
Has two optional arguments for validation, ``max_length`` and Has two optional arguments for validation, ``max_length`` and
``allow_empty_file``. If provided, these ensure that the file name is at ``allow_empty_file``. If provided, these ensure that the file name is at
most the given length, and that validation will succeed even if the file most the given length, and that validation will succeed even if the file
content is empty. content is empty.
To learn more about the ``UploadedFile`` object, see the :doc:`file uploads To learn more about the ``UploadedFile`` object, see the :doc:`file uploads
documentation </topics/http/file-uploads>`. documentation </topics/http/file-uploads>`.
When you use a ``FileField`` in a form, you must also remember to When you use a ``FileField`` in a form, you must also remember to
:ref:`bind the file data to the form <binding-uploaded-files>`. :ref:`bind the file data to the form <binding-uploaded-files>`.
The ``max_length`` error refers to the length of the filename. In the error The ``max_length`` error refers to the length of the filename. In the error
message for that key, ``%(max)d`` will be replaced with the maximum filename message for that key, ``%(max)d`` will be replaced with the maximum filename
length and ``%(length)d`` will be replaced with the current filename length. length and ``%(length)d`` will be replaced with the current filename length.
``FilePathField`` ``FilePathField``
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
@ -536,28 +536,30 @@ length and ``%(length)d`` will be replaced with the current filename length.
* Validates that the selected choice exists in the list of choices. * Validates that the selected choice exists in the list of choices.
* Error message keys: ``required``, ``invalid_choice`` * Error message keys: ``required``, ``invalid_choice``
The field allows choosing from files inside a certain directory. It takes three The field allows choosing from files inside a certain directory. It takes three
extra arguments; only ``path`` is required: extra arguments; only ``path`` is required:
.. attribute:: FilePathField.path .. attribute:: path
The absolute path to the directory whose contents you want listed. This The absolute path to the directory whose contents you want listed. This
directory must exist. directory must exist.
.. attribute:: FilePathField.recursive .. attribute:: recursive
If ``False`` (the default) only the direct contents of ``path`` will be If ``False`` (the default) only the direct contents of ``path`` will be
offered as choices. If ``True``, the directory will be descended into offered as choices. If ``True``, the directory will be descended into
recursively and all descendants will be listed as choices. recursively and all descendants will be listed as choices.
.. attribute:: FilePathField.match .. attribute:: match
A regular expression pattern; only files with names matching this expression A regular expression pattern; only files with names matching this expression
will be allowed as choices. will be allowed as choices.
``FloatField`` ``FloatField``
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
.. class:: FloatField(**kwargs)
* Default widget: ``TextInput`` * Default widget: ``TextInput``
* Empty value: ``None`` * Empty value: ``None``
* Normalizes to: A Python float. * Normalizes to: A Python float.
@ -566,8 +568,8 @@ extra arguments; only ``path`` is required:
* Error message keys: ``required``, ``invalid``, ``max_value``, * Error message keys: ``required``, ``invalid``, ``max_value``,
``min_value`` ``min_value``
Takes two optional arguments for validation, ``max_value`` and ``min_value``. Takes two optional arguments for validation, ``max_value`` and ``min_value``.
These control the range of values permitted in the field. These control the range of values permitted in the field.
``ImageField`` ``ImageField``
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -583,10 +585,10 @@ These control the range of values permitted in the field.
* Error message keys: ``required``, ``invalid``, ``missing``, ``empty``, * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
``invalid_image`` ``invalid_image``
Using an ImageField requires that the `Python Imaging Library`_ is installed. Using an ImageField requires that the `Python Imaging Library`_ is installed.
When you use an ``ImageField`` on a form, you must also remember to When you use an ``ImageField`` on a form, you must also remember to
:ref:`bind the file data to the form <binding-uploaded-files>`. :ref:`bind the file data to the form <binding-uploaded-files>`.
.. _Python Imaging Library: http://www.pythonware.com/products/pil/ .. _Python Imaging Library: http://www.pythonware.com/products/pil/
@ -603,13 +605,13 @@ When you use an ``ImageField`` on a form, you must also remember to
* Error message keys: ``required``, ``invalid``, ``max_value``, * Error message keys: ``required``, ``invalid``, ``max_value``,
``min_value`` ``min_value``
The ``max_value`` and ``min_value`` error messages may contain The ``max_value`` and ``min_value`` error messages may contain
``%(limit_value)s``, which will be substituted by the appropriate limit. ``%(limit_value)s``, which will be substituted by the appropriate limit.
Takes two optional arguments for validation: Takes two optional arguments for validation:
.. attribute:: IntegerField.max_value .. attribute:: max_value
.. attribute:: IntegerField.min_value .. attribute:: min_value
These control the range of values permitted in the field. These control the range of values permitted in the field.
@ -628,11 +630,11 @@ Takes two optional arguments for validation:
``GenericIPAddressField`` ``GenericIPAddressField``
~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
.. class:: GenericIPAddressField(**kwargs)
.. versionadded:: 1.4 .. versionadded:: 1.4
A field containing either an IPv4 or an IPv6 address. .. class:: GenericIPAddressField(**kwargs)
A field containing either an IPv4 or an IPv6 address.
* Default widget: ``TextInput`` * Default widget: ``TextInput``
* Empty value: ``''`` (an empty string) * Empty value: ``''`` (an empty string)
@ -641,26 +643,26 @@ A field containing either an IPv4 or an IPv6 address.
* Validates that the given value is a valid IP address. * Validates that the given value is a valid IP address.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
The IPv6 address normalization follows :rfc:`4291#section-2.2` section 2.2, The IPv6 address normalization follows :rfc:`4291#section-2.2` section 2.2,
including using the IPv4 format suggested in paragraph 3 of that section, like including using the IPv4 format suggested in paragraph 3 of that section, like
``::ffff:192.0.2.0``. For example, ``2001:0::0:01`` would be normalized to ``::ffff:192.0.2.0``. For example, ``2001:0::0:01`` would be normalized to
``2001::1``, and ``::ffff:0a0a:0a0a`` to ``::ffff:10.10.10.10``. All characters ``2001::1``, and ``::ffff:0a0a:0a0a`` to ``::ffff:10.10.10.10``. All characters
are converted to lowercase. are converted to lowercase.
Takes two optional arguments: Takes two optional arguments:
.. attribute:: GenericIPAddressField.protocol .. attribute:: protocol
Limits valid inputs to the specified protocol. Limits valid inputs to the specified protocol.
Accepted values are ``both`` (default), ``IPv4`` Accepted values are ``both`` (default), ``IPv4``
or ``IPv6``. Matching is case insensitive. or ``IPv6``. Matching is case insensitive.
.. attribute:: GenericIPAddressField.unpack_ipv4 .. attribute:: unpack_ipv4
Unpacks IPv4 mapped addresses like ``::ffff::192.0.2.1``. Unpacks IPv4 mapped addresses like ``::ffff::192.0.2.1``.
If this option is enabled that address would be unpacked to If this option is enabled that address would be unpacked to
``192.0.2.1``. Default is disabled. Can only be used ``192.0.2.1``. Default is disabled. Can only be used
when ``protocol`` is set to ``'both'``. when ``protocol`` is set to ``'both'``.
``MultipleChoiceField`` ``MultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
@ -674,20 +676,20 @@ Takes two optional arguments:
of choices. of choices.
* Error message keys: ``required``, ``invalid_choice``, ``invalid_list`` * Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice. replaced with the selected choice.
Takes one extra required argument, ``choices``, as for ``ChoiceField``. Takes one extra required argument, ``choices``, as for ``ChoiceField``.
``TypedMultipleChoiceField`` ``TypedMultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. class:: TypedMultipleChoiceField(**kwargs)
.. versionadded:: 1.3 .. versionadded:: 1.3
Just like a :class:`MultipleChoiceField`, except :class:`TypedMultipleChoiceField` .. class:: TypedMultipleChoiceField(**kwargs)
takes two extra arguments, ``coerce`` and ``empty_value``.
Just like a :class:`MultipleChoiceField`, except :class:`TypedMultipleChoiceField`
takes two extra arguments, ``coerce`` and ``empty_value``.
* Default widget: ``SelectMultiple`` * Default widget: ``SelectMultiple``
* Empty value: Whatever you've given as ``empty_value`` * Empty value: Whatever you've given as ``empty_value``
@ -697,10 +699,10 @@ takes two extra arguments, ``coerce`` and ``empty_value``.
coerced. coerced.
* Error message keys: ``required``, ``invalid_choice`` * Error message keys: ``required``, ``invalid_choice``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice. replaced with the selected choice.
Takes two extra arguments, ``coerce`` and ``empty_value``, as for ``TypedChoiceField``. Takes two extra arguments, ``coerce`` and ``empty_value``, as for ``TypedChoiceField``.
``NullBooleanField`` ``NullBooleanField``
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
@ -724,20 +726,20 @@ Takes two extra arguments, ``coerce`` and ``empty_value``, as for ``TypedChoiceF
expression. expression.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Takes one required argument: Takes one required argument:
.. attribute:: RegexField.regex .. attribute:: regex
A regular expression specified either as a string or a compiled regular A regular expression specified either as a string or a compiled regular
expression object. expression object.
Also takes ``max_length`` and ``min_length``, which work just as they do for Also takes ``max_length`` and ``min_length``, which work just as they do for
``CharField``. ``CharField``.
The optional argument ``error_message`` is also accepted for backwards The optional argument ``error_message`` is also accepted for backwards
compatibility. The preferred way to provide an error message is to use the compatibility. The preferred way to provide an error message is to use the
``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key ``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
and the error message as the value. and the error message as the value.
``SlugField`` ``SlugField``
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -751,8 +753,8 @@ and the error message as the value.
underscores, and hyphens. underscores, and hyphens.
* Error messages: ``required``, ``invalid`` * Error messages: ``required``, ``invalid``
This field is intended for use in representing a model This field is intended for use in representing a model
:class:`~django.db.models.SlugField` in forms. :class:`~django.db.models.SlugField` in forms.
``TimeField`` ``TimeField``
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -766,17 +768,17 @@ This field is intended for use in representing a model
formatted in a particular time format. formatted in a particular time format.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Takes one optional argument: Takes one optional argument:
.. attribute:: TimeField.input_formats .. attribute:: input_formats
A list of formats used to attempt to convert a string to a valid A list of formats used to attempt to convert a string to a valid
``datetime.time`` object. ``datetime.time`` object.
If no ``input_formats`` argument is provided, the default input formats are:: If no ``input_formats`` argument is provided, the default input formats are::
'%H:%M:%S', # '14:30:59' '%H:%M:%S', # '14:30:59'
'%H:%M', # '14:30' '%H:%M', # '14:30'
``URLField`` ``URLField``
~~~~~~~~~~~~ ~~~~~~~~~~~~
@ -789,27 +791,26 @@ If no ``input_formats`` argument is provided, the default input formats are::
* Validates that the given value is a valid URL. * Validates that the given value is a valid URL.
* Error message keys: ``required``, ``invalid``, ``invalid_link`` * Error message keys: ``required``, ``invalid``, ``invalid_link``
Takes the following optional arguments: Takes the following optional arguments:
.. attribute:: URLField.max_length .. attribute:: max_length
.. attribute:: URLField.min_length .. attribute:: min_length
Same as ``CharField.max_length`` and ``CharField.min_length``. These are the same as ``CharField.max_length`` and ``CharField.min_length``.
.. attribute:: URLField.verify_exists .. attribute:: verify_exists
If ``True``, the validator will attempt to load the given URL, raising If ``True``, the validator will attempt to load the given URL, raising
``ValidationError`` if the page gives a 404. Defaults to ``False``. ``ValidationError`` if the page gives a 404. Defaults to ``False``.
.. deprecated:: 1.4 .. deprecated:: 1.4
``verify_exists`` was deprecated for security reasons and will be removed in
Django 1.5. This deprecation also removes ``validator_user_agent``.
``verify_exists`` was deprecated for security reasons and will be removed in .. attribute:: validator_user_agent
Django 1.5. This deprecation also removes ``validator_user_agent``.
.. attribute:: URLField.validator_user_agent String used as the user-agent used when checking for a URL's existence.
Defaults to the value of the :setting:`URL_VALIDATOR_USER_AGENT` setting.
String used as the user-agent used when checking for a URL's existence.
Defaults to the value of the :setting:`URL_VALIDATOR_USER_AGENT` setting.
.. versionchanged:: 1.2 .. versionchanged:: 1.2
The URLField previously did not recognize URLs as valid that contained an IDN The URLField previously did not recognize URLs as valid that contained an IDN
@ -832,20 +833,20 @@ Slightly complex built-in ``Field`` classes
as an argument to the ``ComboField``. as an argument to the ``ComboField``.
* Error message keys: ``required``, ``invalid`` * Error message keys: ``required``, ``invalid``
Takes one extra required argument: Takes one extra required argument:
.. attribute:: ComboField.fields .. attribute:: fields
The list of fields that should be used to validate the field's value (in The list of fields that should be used to validate the field's value (in
the order in which they are provided). the order in which they are provided).
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()]) >>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean('test@example.com') >>> f.clean('test@example.com')
u'test@example.com' u'test@example.com'
>>> f.clean('longemailaddress@example.com') >>> f.clean('longemailaddress@example.com')
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValidationError: [u'Ensure this value has at most 20 characters (it has 28).'] ValidationError: [u'Ensure this value has at most 20 characters (it has 28).']
``MultiValueField`` ``MultiValueField``
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
@ -866,15 +867,15 @@ Takes one extra required argument:
:class:`SplitDateTimeField` is a subclass which combines a time field and :class:`SplitDateTimeField` is a subclass which combines a time field and
a date field into a datetime object. a date field into a datetime object.
Takes one extra required argument: Takes one extra required argument:
.. attribute:: MultiValueField.fields .. attribute:: fields
A list of fields which are cleaned into a single field. Each value in A list of fields which are cleaned into a single field. Each value in
``clean`` is cleaned by the corresponding field in ``fields`` -- the first ``clean`` is cleaned by the corresponding field in ``fields`` -- the first
value is cleaned by the first field, the second value is cleaned by value is cleaned by the first field, the second value is cleaned by
the second field, etc. Once all fields are cleaned, the list of clean the second field, etc. Once all fields are cleaned, the list of clean
values is "compressed" into a single value. values is "compressed" into a single value.
``SplitDateTimeField`` ``SplitDateTimeField``
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
@ -889,23 +890,23 @@ Takes one extra required argument:
* Error message keys: ``required``, ``invalid``, ``invalid_date``, * Error message keys: ``required``, ``invalid``, ``invalid_date``,
``invalid_time`` ``invalid_time``
Takes two optional arguments: Takes two optional arguments:
.. attribute:: SplitDateTimeField.input_date_formats .. attribute:: input_date_formats
A list of formats used to attempt to convert a string to a valid A list of formats used to attempt to convert a string to a valid
``datetime.date`` object. ``datetime.date`` object.
If no ``input_date_formats`` argument is provided, the default input formats If no ``input_date_formats`` argument is provided, the default input formats
for ``DateField`` are used. for ``DateField`` are used.
.. attribute:: SplitDateTimeField.input_time_formats .. attribute:: input_time_formats
A list of formats used to attempt to convert a string to a valid A list of formats used to attempt to convert a string to a valid
``datetime.time`` object. ``datetime.time`` object.
If no ``input_time_formats`` argument is provided, the default input formats If no ``input_time_formats`` argument is provided, the default input formats
for ``TimeField`` are used. for ``TimeField`` are used.
Fields which handle relationships Fields which handle relationships
--------------------------------- ---------------------------------
@ -930,45 +931,45 @@ objects (in the case of ``ModelMultipleChoiceField``) into the
* Validates that the given id exists in the queryset. * Validates that the given id exists in the queryset.
* Error message keys: ``required``, ``invalid_choice`` * Error message keys: ``required``, ``invalid_choice``
Allows the selection of a single model object, suitable for Allows the selection of a single model object, suitable for
representing a foreign key. A single argument is required: representing a foreign key. A single argument is required:
.. attribute:: ModelChoiceField.queryset .. attribute:: queryset
A ``QuerySet`` of model objects from which the choices for the A ``QuerySet`` of model objects from which the choices for the
field will be derived, and which will be used to validate the field will be derived, and which will be used to validate the
user's selection. user's selection.
``ModelChoiceField`` also takes one optional argument: ``ModelChoiceField`` also takes one optional argument:
.. attribute:: ModelChoiceField.empty_label .. attribute:: empty_label
By default the ``<select>`` widget used by ``ModelChoiceField`` will have an By default the ``<select>`` widget used by ``ModelChoiceField`` will have an
empty choice at the top of the list. You can change the text of this empty choice at the top of the list. You can change the text of this
label (which is ``"---------"`` by default) with the ``empty_label`` label (which is ``"---------"`` by default) with the ``empty_label``
attribute, or you can disable the empty label entirely by setting attribute, or you can disable the empty label entirely by setting
``empty_label`` to ``None``:: ``empty_label`` to ``None``::
# A custom empty label # A custom empty label
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)") field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
# No empty label # No empty label
field2 = forms.ModelChoiceField(queryset=..., empty_label=None) field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
Note that if a ``ModelChoiceField`` is required and has a default Note that if a ``ModelChoiceField`` is required and has a default
initial value, no empty choice is created (regardless of the value initial value, no empty choice is created (regardless of the value
of ``empty_label``). of ``empty_label``).
The ``__unicode__`` method of the model will be called to generate The ``__unicode__`` method of the model will be called to generate
string representations of the objects for use in the field's choices; string representations of the objects for use in the field's choices;
to provide customized representations, subclass ``ModelChoiceField`` to provide customized representations, subclass ``ModelChoiceField``
and override ``label_from_instance``. This method will receive a model and override ``label_from_instance``. This method will receive a model
object, and should return a string suitable for representing it. For object, and should return a string suitable for representing it. For
example:: example::
class MyModelChoiceField(ModelChoiceField): class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj): def label_from_instance(self, obj):
return "My Object #%i" % obj.id return "My Object #%i" % obj.id
``ModelMultipleChoiceField`` ``ModelMultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -983,16 +984,16 @@ example::
* Error message keys: ``required``, ``list``, ``invalid_choice``, * Error message keys: ``required``, ``list``, ``invalid_choice``,
``invalid_pk_value`` ``invalid_pk_value``
Allows the selection of one or more model objects, suitable for Allows the selection of one or more model objects, suitable for
representing a many-to-many relation. As with :class:`ModelChoiceField`, representing a many-to-many relation. As with :class:`ModelChoiceField`,
you can use ``label_from_instance`` to customize the object you can use ``label_from_instance`` to customize the object
representations, and ``queryset`` is a required parameter: representations, and ``queryset`` is a required parameter:
.. attribute:: ModelMultipleChoiceField.queryset .. attribute:: queryset
A ``QuerySet`` of model objects from which the choices for the A ``QuerySet`` of model objects from which the choices for the
field will be derived, and which will be used to validate the field will be derived, and which will be used to validate the
user's selection. user's selection.
Creating custom fields Creating custom fields
---------------------- ----------------------

View File

@ -28,72 +28,72 @@ after the field's ``to_python`` and ``validate`` methods have been called.
Validation of a Form is split into several steps, which can be customized or Validation of a Form is split into several steps, which can be customized or
overridden: overridden:
* The ``to_python()`` method on a Field is the first step in every * The ``to_python()`` method on a Field is the first step in every
validation. It coerces the value to correct datatype and raises validation. It coerces the value to correct datatype and raises
``ValidationError`` if that is not possible. This method accepts the raw ``ValidationError`` if that is not possible. This method accepts the raw
value from the widget and returns the converted value. For example, a value from the widget and returns the converted value. For example, a
FloatField will turn the data into a Python ``float`` or raise a FloatField will turn the data into a Python ``float`` or raise a
``ValidationError``. ``ValidationError``.
* The ``validate()`` method on a Field handles field-specific validation * The ``validate()`` method on a Field handles field-specific validation
that is not suitable for a validator, It takes a value that has been that is not suitable for a validator, It takes a value that has been
coerced to correct datatype and raises ``ValidationError`` on any error. coerced to correct datatype and raises ``ValidationError`` on any error.
This method does not return anything and shouldn't alter the value. You This method does not return anything and shouldn't alter the value. You
should override it to handle validation logic that you can't or don't should override it to handle validation logic that you can't or don't
want to put in a validator. want to put in a validator.
* The ``run_validators()`` method on a Field runs all of the field's * The ``run_validators()`` method on a Field runs all of the field's
validators and aggregates all the errors into a single validators and aggregates all the errors into a single
``ValidationError``. You shouldn't need to override this method. ``ValidationError``. You shouldn't need to override this method.
* The ``clean()`` method on a Field subclass. This is responsible for * The ``clean()`` method on a Field subclass. This is responsible for
running ``to_python``, ``validate`` and ``run_validators`` in the correct running ``to_python``, ``validate`` and ``run_validators`` in the correct
order and propagating their errors. If, at any time, any of the methods order and propagating their errors. If, at any time, any of the methods
raise ``ValidationError``, the validation stops and that error is raised. raise ``ValidationError``, the validation stops and that error is raised.
This method returns the clean data, which is then inserted into the This method returns the clean data, which is then inserted into the
``cleaned_data`` dictionary of the form. ``cleaned_data`` dictionary of the form.
* The ``clean_<fieldname>()`` method in a form subclass -- where * The ``clean_<fieldname>()`` method in a form subclass -- where
``<fieldname>`` is replaced with the name of the form field attribute. ``<fieldname>`` is replaced with the name of the form field attribute.
This method does any cleaning that is specific to that particular This method does any cleaning that is specific to that particular
attribute, unrelated to the type of field that it is. This method is not attribute, unrelated to the type of field that it is. This method is not
passed any parameters. You will need to look up the value of the field passed any parameters. You will need to look up the value of the field
in ``self.cleaned_data`` and remember that it will be a Python object in ``self.cleaned_data`` and remember that it will be a Python object
at this point, not the original string submitted in the form (it will be at this point, not the original string submitted in the form (it will be
in ``cleaned_data`` because the general field ``clean()`` method, above, in ``cleaned_data`` because the general field ``clean()`` method, above,
has already cleaned the data once). has already cleaned the data once).
For example, if you wanted to validate that the contents of a For example, if you wanted to validate that the contents of a
``CharField`` called ``serialnumber`` was unique, ``CharField`` called ``serialnumber`` was unique,
``clean_serialnumber()`` would be the right place to do this. You don't ``clean_serialnumber()`` would be the right place to do this. You don't
need a specific field (it's just a ``CharField``), but you want a need a specific field (it's just a ``CharField``), but you want a
formfield-specific piece of validation and, possibly, formfield-specific piece of validation and, possibly,
cleaning/normalizing the data. cleaning/normalizing the data.
Just like the general field ``clean()`` method, above, this method Just like the general field ``clean()`` method, above, this method
should return the cleaned data, regardless of whether it changed should return the cleaned data, regardless of whether it changed
anything or not. anything or not.
* The Form subclass's ``clean()`` method. This method can perform * The Form subclass's ``clean()`` method. This method can perform
any validation that requires access to multiple fields from the form at any validation that requires access to multiple fields from the form at
once. This is where you might put in things to check that if field ``A`` once. This is where you might put in things to check that if field ``A``
is supplied, field ``B`` must contain a valid email address and the is supplied, field ``B`` must contain a valid email address and the
like. The data that this method returns is the final ``cleaned_data`` like. The data that this method returns is the final ``cleaned_data``
attribute for the form, so don't forget to return the full list of attribute for the form, so don't forget to return the full list of
cleaned data if you override this method (by default, ``Form.clean()`` cleaned data if you override this method (by default, ``Form.clean()``
just returns ``self.cleaned_data``). just returns ``self.cleaned_data``).
Note that any errors raised by your ``Form.clean()`` override will not Note that any errors raised by your ``Form.clean()`` override will not
be associated with any field in particular. They go into a special be associated with any field in particular. They go into a special
"field" (called ``__all__``), which you can access via the "field" (called ``__all__``), which you can access via the
``non_field_errors()`` method if you need to. If you want to attach ``non_field_errors()`` method if you need to. If you want to attach
errors to a specific field in the form, you will need to access the errors to a specific field in the form, you will need to access the
``_errors`` attribute on the form, which is `described later`_. ``_errors`` attribute on the form, which is `described later`_.
Also note that there are special considerations when overriding Also note that there are special considerations when overriding
the ``clean()`` method of a ``ModelForm`` subclass. (see the the ``clean()`` method of a ``ModelForm`` subclass. (see the
:ref:`ModelForm documentation :ref:`ModelForm documentation
<overriding-modelform-clean-method>` for more information) <overriding-modelform-clean-method>` for more information)
These methods are run in the order given above, one field at a time. That is, These methods are run in the order given above, one field at a time. That is,
for each field in the form (in the order they are declared in the form for each field in the form (in the order they are declared in the form

View File

@ -21,16 +21,14 @@ which widget is used on which field, see the documentation about
However, if you want to use a different widget for a field, you can However, if you want to use a different widget for a field, you can
just use the :attr:`~Field.widget` argument on the field definition. For just use the :attr:`~Field.widget` argument on the field definition. For
example: example::
.. code-block:: python from django import forms
from django import forms class CommentForm(forms.Form):
name = forms.CharField()
class CommentForm(forms.Form): url = forms.URLField()
name = forms.CharField() comment = forms.CharField(widget=forms.Textarea)
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
This would specify a form with a comment that uses a larger :class:`Textarea` This would specify a form with a comment that uses a larger :class:`Textarea`
widget, rather than the default :class:`TextInput` widget. widget, rather than the default :class:`TextInput` widget.
@ -42,25 +40,23 @@ Setting arguments for widgets
Many widgets have optional extra arguments; they can be set when defining the Many widgets have optional extra arguments; they can be set when defining the
widget on the field. In the following example, the widget on the field. In the following example, the
:attr:`~SelectDateWidget.years` attribute is set for a :attr:`~SelectDateWidget.years` attribute is set for a
:class:`~django.forms.extras.widgets.SelectDateWidget`: :class:`~django.forms.extras.widgets.SelectDateWidget`::
.. code-block:: python from django.forms.fields import DateField, ChoiceField, MultipleChoiceField
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
from django.forms.extras.widgets import SelectDateWidget
from django.forms.fields import DateField, ChoiceField, MultipleChoiceField BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'))
from django.forms.extras.widgets import SelectDateWidget FAVORITE_COLORS_CHOICES = (('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'))
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982') class SimpleForm(forms.Form):
GENDER_CHOICES = (('m', 'Male'), ('f', 'Female')) birth_year = DateField(widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES))
FAVORITE_COLORS_CHOICES = (('blue', 'Blue'), gender = ChoiceField(widget=RadioSelect, choices=GENDER_CHOICES)
('green', 'Green'), favorite_colors = forms.MultipleChoiceField(required=False,
('black', 'Black')) widget=CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES)
class SimpleForm(forms.Form):
birth_year = DateField(widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES))
gender = ChoiceField(widget=RadioSelect, choices=GENDER_CHOICES)
favorite_colors = forms.MultipleChoiceField(required=False,
widget=CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES)
See the :ref:`built-in widgets` for more information about which widgets See the :ref:`built-in widgets` for more information about which widgets
are available and which arguments they accept. are available and which arguments they accept.
@ -78,21 +74,19 @@ buttons.
:class:`Select` widgets are used by default on :class:`ChoiceField` fields. The :class:`Select` widgets are used by default on :class:`ChoiceField` fields. The
choices displayed on the widget are inherited from the :class:`ChoiceField` and choices displayed on the widget are inherited from the :class:`ChoiceField` and
changing :attr:`ChoiceField.choices` will update :attr:`Select.choices`. For changing :attr:`ChoiceField.choices` will update :attr:`Select.choices`. For
example: example::
.. code-block:: python >>> from django import forms
>>> CHOICES = (('1', 'First',), ('2', 'Second',)))
>>> from django import forms >>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
>>> CHOICES = (('1', 'First',), ('2', 'Second',))) >>> choice_field.choices
>>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES) [('1', 'First'), ('2', 'Second')]
>>> choice_field.choices >>> choice_field.widget.choices
[('1', 'First'), ('2', 'Second')] [('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices >>> choice_field.widget.choices = ()
[('1', 'First'), ('2', 'Second')] >>> choice_field.choices = (('1', 'First and only',),)
>>> choice_field.widget.choices = () >>> choice_field.widget.choices
>>> choice_field.choices = (('1', 'First and only',),) [('1', 'First and only')]
>>> choice_field.widget.choices
[('1', 'First and only')]
Widgets which offer a :attr:`~Select.choices` attribute can however be used Widgets which offer a :attr:`~Select.choices` attribute can however be used
@ -113,55 +107,46 @@ specify additional attributes for each widget. When you specify a
widget, you can provide a list of attributes that will be added to the widget, you can provide a list of attributes that will be added to the
rendered HTML for the widget. rendered HTML for the widget.
For example, take the following simple form: For example, take the following simple form::
.. code-block:: python from django import forms
from django import forms class CommentForm(forms.Form):
name = forms.CharField()
class CommentForm(forms.Form): url = forms.URLField()
name = forms.CharField() comment = forms.CharField()
url = forms.URLField()
comment = forms.CharField()
This form will include three default :class:`TextInput` widgets, with default This form will include three default :class:`TextInput` widgets, with default
rendering -- no CSS class, no extra attributes. This means that the input boxes rendering -- no CSS class, no extra attributes. This means that the input boxes
provided for each widget will be rendered exactly the same: provided for each widget will be rendered exactly the same::
.. code-block:: python
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
On a real Web page, you probably don't want every widget to look the same. You On a real Web page, you probably don't want every widget to look the same. You
might want a larger input element for the comment, and you might want the might want a larger input element for the comment, and you might want the
'name' widget to have some special CSS class. To do this, you use the 'name' widget to have some special CSS class. To do this, you use the
:attr:`Widget.attrs` argument when creating the widget: :attr:`Widget.attrs` argument when creating the widget:
For example: For example::
.. code-block:: python class CommentForm(forms.Form):
name = forms.CharField(
class CommentForm(forms.Form): widget=forms.TextInput(attrs={'class':'special'}))
name = forms.CharField( url = forms.URLField()
widget=forms.TextInput(attrs={'class':'special'})) comment = forms.CharField(
url = forms.URLField() widget=forms.TextInput(attrs={'size':'40'}))
comment = forms.CharField(
widget=forms.TextInput(attrs={'size':'40'}))
Django will then include the extra attributes in the rendered output: Django will then include the extra attributes in the rendered output:
.. code-block:: python >>> f = CommentForm(auto_id=False)
>>> f.as_table()
>>> f = CommentForm(auto_id=False) <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
>>> f.as_table() <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr> <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
.. _built-in widgets: .. _built-in widgets:
@ -411,9 +396,7 @@ commonly used groups of widgets:
:class:`MultiWidget`'s subclasses must implement. This method takes a :class:`MultiWidget`'s subclasses must implement. This method takes a
single "compressed" value and returns a ``list``. An example of this is how single "compressed" value and returns a ``list``. An example of this is how
:class:`SplitDateTimeWidget` turns a :class:`datetime` value into a list :class:`SplitDateTimeWidget` turns a :class:`datetime` value into a list
with date and time split into two seperate values: with date and time split into two seperate values::
.. code-block:: python
class SplitDateTimeWidget(MultiWidget): class SplitDateTimeWidget(MultiWidget):

File diff suppressed because it is too large Load Diff

View File

@ -36,38 +36,38 @@ defines. See the :doc:`cache documentation </topics/cache>`.
Adds a few conveniences for perfectionists: Adds a few conveniences for perfectionists:
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS` * Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
setting, which should be a list of strings. setting, which should be a list of strings.
* Performs URL rewriting based on the :setting:`APPEND_SLASH` and * Performs URL rewriting based on the :setting:`APPEND_SLASH` and
:setting:`PREPEND_WWW` settings. :setting:`PREPEND_WWW` settings.
If :setting:`APPEND_SLASH` is ``True`` and the initial URL doesn't end If :setting:`APPEND_SLASH` is ``True`` and the initial URL doesn't end
with a slash, and it is not found in the URLconf, then a new URL is with a slash, and it is not found in the URLconf, then a new URL is
formed by appending a slash at the end. If this new URL is found in the formed by appending a slash at the end. If this new URL is found in the
URLconf, then Django redirects the request to this new URL. Otherwise, URLconf, then Django redirects the request to this new URL. Otherwise,
the initial URL is processed as usual. the initial URL is processed as usual.
For example, ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if For example, ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if
you don't have a valid URL pattern for ``foo.com/bar`` but *do* have a you don't have a valid URL pattern for ``foo.com/bar`` but *do* have a
valid pattern for ``foo.com/bar/``. valid pattern for ``foo.com/bar/``.
If :setting:`PREPEND_WWW` is ``True``, URLs that lack a leading "www." If :setting:`PREPEND_WWW` is ``True``, URLs that lack a leading "www."
will be redirected to the same URL with a leading "www." will be redirected to the same URL with a leading "www."
Both of these options are meant to normalize URLs. The philosophy is that Both of these options are meant to normalize URLs. The philosophy is that
each URL should exist in one, and only one, place. Technically a URL each URL should exist in one, and only one, place. Technically a URL
``foo.com/bar`` is distinct from ``foo.com/bar/`` -- a search-engine ``foo.com/bar`` is distinct from ``foo.com/bar/`` -- a search-engine
indexer would treat them as separate URLs -- so it's best practice to indexer would treat them as separate URLs -- so it's best practice to
normalize URLs. normalize URLs.
* Sends broken link notification emails to :setting:`MANAGERS` if * Sends broken link notification emails to :setting:`MANAGERS` if
:setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``. :setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``.
* Handles ETags based on the :setting:`USE_ETAGS` setting. If * Handles ETags based on the :setting:`USE_ETAGS` setting. If
:setting:`USE_ETAGS` is set to ``True``, Django will calculate an ETag :setting:`USE_ETAGS` is set to ``True``, Django will calculate an ETag
for each request by MD5-hashing the page content, and it'll take care of for each request by MD5-hashing the page content, and it'll take care of
sending ``Not Modified`` responses, if appropriate. sending ``Not Modified`` responses, if appropriate.
View metadata middleware View metadata middleware
------------------------ ------------------------

View File

@ -510,23 +510,23 @@ Has one **required** argument:
to be passed along to the storage system. The two arguments that will be to be passed along to the storage system. The two arguments that will be
passed are: passed are:
====================== =============================================== ====================== ===============================================
Argument Description Argument Description
====================== =============================================== ====================== ===============================================
``instance`` An instance of the model where the ``instance`` An instance of the model where the
``FileField`` is defined. More specifically, ``FileField`` is defined. More specifically,
this is the particular instance where the this is the particular instance where the
current file is being attached. current file is being attached.
In most cases, this object will not have been In most cases, this object will not have been
saved to the database yet, so if it uses the saved to the database yet, so if it uses the
default ``AutoField``, *it might not yet have a default ``AutoField``, *it might not yet have a
value for its primary key field*. value for its primary key field*.
``filename`` The filename that was originally given to the ``filename`` The filename that was originally given to the
file. This may or may not be taken into account file. This may or may not be taken into account
when determining the final destination path. when determining the final destination path.
====================== =============================================== ====================== ===============================================
Also has one optional argument: Also has one optional argument:
@ -541,22 +541,22 @@ widget).
Using a :class:`FileField` or an :class:`ImageField` (see below) in a model Using a :class:`FileField` or an :class:`ImageField` (see below) in a model
takes a few steps: takes a few steps:
1. In your settings file, you'll need to define :setting:`MEDIA_ROOT` as the 1. In your settings file, you'll need to define :setting:`MEDIA_ROOT` as the
full path to a directory where you'd like Django to store uploaded files. full path to a directory where you'd like Django to store uploaded files.
(For performance, these files are not stored in the database.) Define (For performance, these files are not stored in the database.) Define
:setting:`MEDIA_URL` as the base public URL of that directory. Make sure :setting:`MEDIA_URL` as the base public URL of that directory. Make sure
that this directory is writable by the Web server's user account. that this directory is writable by the Web server's user account.
2. Add the :class:`FileField` or :class:`ImageField` to your model, making 2. Add the :class:`FileField` or :class:`ImageField` to your model, making
sure to define the :attr:`~FileField.upload_to` option to tell Django sure to define the :attr:`~FileField.upload_to` option to tell Django
to which subdirectory of :setting:`MEDIA_ROOT` it should upload files. to which subdirectory of :setting:`MEDIA_ROOT` it should upload files.
3. All that will be stored in your database is a path to the file 3. All that will be stored in your database is a path to the file
(relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the (relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the
convenience :attr:`~django.core.files.File.url` function provided by convenience :attr:`~django.core.files.File.url` function provided by
Django. For example, if your :class:`ImageField` is called ``mug_shot``, Django. For example, if your :class:`ImageField` is called ``mug_shot``,
you can get the absolute path to your image in a template with you can get the absolute path to your image in a template with
``{{ object.mug_shot.url }}``. ``{{ object.mug_shot.url }}``.
For example, say your :setting:`MEDIA_ROOT` is set to ``'/home/media'``, and For example, say your :setting:`MEDIA_ROOT` is set to ``'/home/media'``, and
:attr:`~FileField.upload_to` is set to ``'photos/%Y/%m/%d'``. The ``'%Y/%m/%d'`` :attr:`~FileField.upload_to` is set to ``'photos/%Y/%m/%d'``. The ``'%Y/%m/%d'``

View File

@ -34,9 +34,9 @@ Validating objects
There are three steps involved in validating a model: There are three steps involved in validating a model:
1. Validate the model fields 1. Validate the model fields
2. Validate the model as a whole 2. Validate the model as a whole
3. Validate the field uniqueness 3. Validate the field uniqueness
All three steps are performed when you call a model's All three steps are performed when you call a model's
:meth:`~Model.full_clean()` method. :meth:`~Model.full_clean()` method.
@ -211,43 +211,43 @@ What happens when you save?
When you save an object, Django performs the following steps: When you save an object, Django performs the following steps:
1. **Emit a pre-save signal.** The :doc:`signal </ref/signals>` 1. **Emit a pre-save signal.** The :doc:`signal </ref/signals>`
:attr:`django.db.models.signals.pre_save` is sent, allowing any :attr:`django.db.models.signals.pre_save` is sent, allowing any
functions listening for that signal to take some customized functions listening for that signal to take some customized
action. action.
2. **Pre-process the data.** Each field on the object is asked to 2. **Pre-process the data.** Each field on the object is asked to
perform any automated data modification that the field may need perform any automated data modification that the field may need
to perform. to perform.
Most fields do *no* pre-processing — the field data is kept as-is. Most fields do *no* pre-processing — the field data is kept as-is.
Pre-processing is only used on fields that have special behavior. For Pre-processing is only used on fields that have special behavior. For
example, if your model has a :class:`~django.db.models.DateField` with example, if your model has a :class:`~django.db.models.DateField` with
``auto_now=True``, the pre-save phase will alter the data in the object ``auto_now=True``, the pre-save phase will alter the data in the object
to ensure that the date field contains the current date stamp. (Our to ensure that the date field contains the current date stamp. (Our
documentation doesn't yet include a list of all the fields with this documentation doesn't yet include a list of all the fields with this
"special behavior.") "special behavior.")
3. **Prepare the data for the database.** Each field is asked to provide 3. **Prepare the data for the database.** Each field is asked to provide
its current value in a data type that can be written to the database. its current value in a data type that can be written to the database.
Most fields require *no* data preparation. Simple data types, such as Most fields require *no* data preparation. Simple data types, such as
integers and strings, are 'ready to write' as a Python object. However, integers and strings, are 'ready to write' as a Python object. However,
more complex data types often require some modification. more complex data types often require some modification.
For example, :class:`~django.db.models.DateField` fields use a Python For example, :class:`~django.db.models.DateField` fields use a Python
``datetime`` object to store data. Databases don't store ``datetime`` ``datetime`` object to store data. Databases don't store ``datetime``
objects, so the field value must be converted into an ISO-compliant date objects, so the field value must be converted into an ISO-compliant date
string for insertion into the database. string for insertion into the database.
4. **Insert the data into the database.** The pre-processed, prepared 4. **Insert the data into the database.** The pre-processed, prepared
data is then composed into an SQL statement for insertion into the data is then composed into an SQL statement for insertion into the
database. database.
5. **Emit a post-save signal.** The signal 5. **Emit a post-save signal.** The signal
:attr:`django.db.models.signals.post_save` is sent, allowing :attr:`django.db.models.signals.post_save` is sent, allowing
any functions listening for that signal to take some customized any functions listening for that signal to take some customized
action. action.
How Django knows to UPDATE vs. INSERT How Django knows to UPDATE vs. INSERT
------------------------------------- -------------------------------------
@ -257,14 +257,14 @@ for creating and changing objects. Django abstracts the need to use ``INSERT``
or ``UPDATE`` SQL statements. Specifically, when you call ``save()``, Django or ``UPDATE`` SQL statements. Specifically, when you call ``save()``, Django
follows this algorithm: follows this algorithm:
* If the object's primary key attribute is set to a value that evaluates to * If the object's primary key attribute is set to a value that evaluates to
``True`` (i.e., a value other than ``None`` or the empty string), Django ``True`` (i.e., a value other than ``None`` or the empty string), Django
executes a ``SELECT`` query to determine whether a record with the given executes a ``SELECT`` query to determine whether a record with the given
primary key already exists. primary key already exists.
* If the record with the given primary key does already exist, Django * If the record with the given primary key does already exist, Django
executes an ``UPDATE`` query. executes an ``UPDATE`` query.
* If the object's primary key attribute is *not* set, or if it's set but a * If the object's primary key attribute is *not* set, or if it's set but a
record doesn't exist, Django executes an ``INSERT``. record doesn't exist, Django executes an ``INSERT``.
The one gotcha here is that you should be careful not to specify a primary-key The one gotcha here is that you should be careful not to specify a primary-key
value explicitly when saving new objects, if you cannot guarantee the value explicitly when saving new objects, if you cannot guarantee the

View File

@ -107,21 +107,21 @@ Django quotes column and table names behind the scenes.
the *only* difference when ``managed=False``. All other aspects of the *only* difference when ``managed=False``. All other aspects of
model handling are exactly the same as normal. This includes model handling are exactly the same as normal. This includes
1. Adding an automatic primary key field to the model if you don't 1. Adding an automatic primary key field to the model if you don't
declare it. To avoid confusion for later code readers, it's declare it. To avoid confusion for later code readers, it's
recommended to specify all the columns from the database table you recommended to specify all the columns from the database table you
are modeling when using unmanaged models. are modeling when using unmanaged models.
2. If a model with ``managed=False`` contains a 2. If a model with ``managed=False`` contains a
:class:`~django.db.models.ManyToManyField` that points to another :class:`~django.db.models.ManyToManyField` that points to another
unmanaged model, then the intermediate table for the many-to-many unmanaged model, then the intermediate table for the many-to-many
join will also not be created. However, the intermediary table join will also not be created. However, the intermediary table
between one managed and one unmanaged model *will* be created. between one managed and one unmanaged model *will* be created.
If you need to change this default behavior, create the intermediary If you need to change this default behavior, create the intermediary
table as an explicit model (with ``managed`` set as needed) and use table as an explicit model (with ``managed`` set as needed) and use
the :attr:`ManyToManyField.through` attribute to make the relation the :attr:`ManyToManyField.through` attribute to make the relation
use your custom model. use your custom model.
For tests involving models with ``managed=False``, it's up to you to ensure For tests involving models with ``managed=False``, it's up to you to ensure
the correct tables are created as part of the test setup. the correct tables are created as part of the test setup.

View File

@ -9,28 +9,28 @@ Related objects reference
A "related manager" is a manager used in a one-to-many or many-to-many A "related manager" is a manager used in a one-to-many or many-to-many
related context. This happens in two cases: related context. This happens in two cases:
* The "other side" of a :class:`~django.db.models.ForeignKey` relation. * The "other side" of a :class:`~django.db.models.ForeignKey` relation.
That is:: That is::
class Reporter(models.Model): class Reporter(models.Model):
... ...
class Article(models.Model): class Article(models.Model):
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter)
In the above example, the methods below will be available on In the above example, the methods below will be available on
the manager ``reporter.article_set``. the manager ``reporter.article_set``.
* Both sides of a :class:`~django.db.models.ManyToManyField` relation:: * Both sides of a :class:`~django.db.models.ManyToManyField` relation::
class Topping(models.Model): class Topping(models.Model):
... ...
class Pizza(models.Model): class Pizza(models.Model):
toppings = models.ManyToManyField(Topping) toppings = models.ManyToManyField(Topping)
In this example, the methods below will be available both on In this example, the methods below will be available both on
``topping.pizza_set`` and on ``pizza.toppings``. ``topping.pizza_set`` and on ``pizza.toppings``.
These related managers have some extra methods: These related managers have some extra methods:

View File

@ -125,20 +125,20 @@ All attributes except ``session`` should be considered read-only.
Available headers depend on the client and server, but here are some Available headers depend on the client and server, but here are some
examples: examples:
* ``CONTENT_LENGTH`` -- the length of the request body (as a string). * ``CONTENT_LENGTH`` -- the length of the request body (as a string).
* ``CONTENT_TYPE`` -- the MIME type of the request body. * ``CONTENT_TYPE`` -- the MIME type of the request body.
* ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response. * ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response.
* ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response. * ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response.
* ``HTTP_HOST`` -- The HTTP Host header sent by the client. * ``HTTP_HOST`` -- The HTTP Host header sent by the client.
* ``HTTP_REFERER`` -- The referring page, if any. * ``HTTP_REFERER`` -- The referring page, if any.
* ``HTTP_USER_AGENT`` -- The client's user-agent string. * ``HTTP_USER_AGENT`` -- The client's user-agent string.
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string. * ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
* ``REMOTE_ADDR`` -- The IP address of the client. * ``REMOTE_ADDR`` -- The IP address of the client.
* ``REMOTE_HOST`` -- The hostname of the client. * ``REMOTE_HOST`` -- The hostname of the client.
* ``REMOTE_USER`` -- The user authenticated by the Web server, if any. * ``REMOTE_USER`` -- The user authenticated by the Web server, if any.
* ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``. * ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
* ``SERVER_NAME`` -- The hostname of the server. * ``SERVER_NAME`` -- The hostname of the server.
* ``SERVER_PORT`` -- The port of the server (as a string). * ``SERVER_PORT`` -- The port of the server (as a string).
With the exception of ``CONTENT_LENGTH`` and ``CONTENT_TYPE``, as given With the exception of ``CONTENT_LENGTH`` and ``CONTENT_TYPE``, as given
above, any HTTP headers in the request are converted to ``META`` keys by above, any HTTP headers in the request are converted to ``META`` keys by
@ -549,10 +549,10 @@ Passing iterators
Finally, you can pass ``HttpResponse`` an iterator rather than passing it Finally, you can pass ``HttpResponse`` an iterator rather than passing it
hard-coded strings. If you use this technique, follow these guidelines: hard-coded strings. If you use this technique, follow these guidelines:
* The iterator should return strings. * The iterator should return strings.
* If an :class:`HttpResponse` has been initialized with an iterator as its * If an :class:`HttpResponse` has been initialized with an iterator as its
content, you can't use the :class:`HttpResponse` instance as a file-like content, you can't use the :class:`HttpResponse` instance as a file-like
object. Doing so will raise ``Exception``. object. Doing so will raise ``Exception``.
Setting headers Setting headers
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -649,27 +649,27 @@ Methods
Sets a cookie. The parameters are the same as in the :class:`Cookie.Morsel` Sets a cookie. The parameters are the same as in the :class:`Cookie.Morsel`
object in the Python standard library. object in the Python standard library.
* ``max_age`` should be a number of seconds, or ``None`` (default) if * ``max_age`` should be a number of seconds, or ``None`` (default) if
the cookie should last only as long as the client's browser session. the cookie should last only as long as the client's browser session.
If ``expires`` is not specified, it will be calculated. If ``expires`` is not specified, it will be calculated.
* ``expires`` should either be a string in the format * ``expires`` should either be a string in the format
``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object ``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
in UTC. If ``expires`` is a ``datetime`` object, the ``max_age`` in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
will be calculated. will be calculated.
* Use ``domain`` if you want to set a cross-domain cookie. For example, * Use ``domain`` if you want to set a cross-domain cookie. For example,
``domain=".lawrence.com"`` will set a cookie that is readable by ``domain=".lawrence.com"`` will set a cookie that is readable by
the domains www.lawrence.com, blogs.lawrence.com and the domains www.lawrence.com, blogs.lawrence.com and
calendars.lawrence.com. Otherwise, a cookie will only be readable by calendars.lawrence.com. Otherwise, a cookie will only be readable by
the domain that set it. the domain that set it.
* Use ``httponly=True`` if you want to prevent client-side * Use ``httponly=True`` if you want to prevent client-side
JavaScript from having access to the cookie. JavaScript from having access to the cookie.
HTTPOnly_ is a flag included in a Set-Cookie HTTP response HTTPOnly_ is a flag included in a Set-Cookie HTTP response
header. It is not part of the :rfc:`2109` standard for cookies, header. It is not part of the :rfc:`2109` standard for cookies,
and it isn't honored consistently by all browsers. However, and it isn't honored consistently by all browsers. However,
when it is honored, it can be a useful way to mitigate the when it is honored, it can be a useful way to mitigate the
risk of client side script accessing the protected cookie risk of client side script accessing the protected cookie
data. data.
.. _HTTPOnly: http://www.owasp.org/index.php/HTTPOnly .. _HTTPOnly: http://www.owasp.org/index.php/HTTPOnly

View File

@ -147,12 +147,12 @@ Default: ``''`` (Empty string)
The cache backend to use. The built-in cache backends are: The cache backend to use. The built-in cache backends are:
* ``'django.core.cache.backends.db.DatabaseCache'`` * ``'django.core.cache.backends.db.DatabaseCache'``
* ``'django.core.cache.backends.dummy.DummyCache'`` * ``'django.core.cache.backends.dummy.DummyCache'``
* ``'django.core.cache.backends.filebased.FileBasedCache'`` * ``'django.core.cache.backends.filebased.FileBasedCache'``
* ``'django.core.cache.backends.locmem.LocMemCache'`` * ``'django.core.cache.backends.locmem.LocMemCache'``
* ``'django.core.cache.backends.memcached.MemcachedCache'`` * ``'django.core.cache.backends.memcached.MemcachedCache'``
* ``'django.core.cache.backends.memcached.PyLibMCCache'`` * ``'django.core.cache.backends.memcached.PyLibMCCache'``
You can use a cache backend that doesn't ship with Django by setting You can use a cache backend that doesn't ship with Django by setting
:setting:`BACKEND <CACHE-BACKEND>` to a fully-qualified path of a cache :setting:`BACKEND <CACHE-BACKEND>` to a fully-qualified path of a cache
@ -412,10 +412,10 @@ Default: ``''`` (Empty string)
The database backend to use. The built-in database backends are: The database backend to use. The built-in database backends are:
* ``'django.db.backends.postgresql_psycopg2'`` * ``'django.db.backends.postgresql_psycopg2'``
* ``'django.db.backends.mysql'`` * ``'django.db.backends.mysql'``
* ``'django.db.backends.sqlite3'`` * ``'django.db.backends.sqlite3'``
* ``'django.db.backends.oracle'`` * ``'django.db.backends.oracle'``
You can use a database backend that doesn't ship with Django by setting You can use a database backend that doesn't ship with Django by setting
``ENGINE`` to a fully-qualified path (i.e. ``ENGINE`` to a fully-qualified path (i.e.
@ -1165,9 +1165,9 @@ Default: ``()`` (Empty tuple)
A tuple of IP addresses, as strings, that: A tuple of IP addresses, as strings, that:
* See debug comments, when :setting:`DEBUG` is ``True`` * See debug comments, when :setting:`DEBUG` is ``True``
* Receive X headers if the ``XViewMiddleware`` is installed (see * Receive X headers if the ``XViewMiddleware`` is installed (see
:doc:`/topics/http/middleware`) :doc:`/topics/http/middleware`)
.. setting:: LANGUAGE_CODE .. setting:: LANGUAGE_CODE
@ -1389,11 +1389,11 @@ MESSAGE_TAGS
Default:: Default::
{messages.DEBUG: 'debug', {messages.DEBUG: 'debug',
messages.INFO: 'info', messages.INFO: 'info',
messages.SUCCESS: 'success', messages.SUCCESS: 'success',
messages.WARNING: 'warning', messages.WARNING: 'warning',
messages.ERROR: 'error',} messages.ERROR: 'error',}
Sets the mapping of message levels to message tags. See the Sets the mapping of message levels to message tags. See the
:doc:`messages documentation </ref/contrib/messages>` for more details. :doc:`messages documentation </ref/contrib/messages>` for more details.
@ -1649,10 +1649,10 @@ Default: ``django.contrib.sessions.backends.db``
Controls where Django stores session data. Valid values are: Controls where Django stores session data. Valid values are:
* ``'django.contrib.sessions.backends.db'`` * ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'`` * ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'`` * ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'`` * ``'django.contrib.sessions.backends.cached_db'``
See :doc:`/topics/http/sessions`. See :doc:`/topics/http/sessions`.
@ -1989,12 +1989,12 @@ and models will automatically operate in the correct time zone.
However, Django won't set the ``TZ`` environment variable under the However, Django won't set the ``TZ`` environment variable under the
following conditions: following conditions:
* If you're using the manual configuration option as described in * If you're using the manual configuration option as described in
:ref:`manually configuring settings :ref:`manually configuring settings
<settings-without-django-settings-module>`, or <settings-without-django-settings-module>`, or
* If you specify ``TIME_ZONE = None``. This will cause Django to fall * If you specify ``TIME_ZONE = None``. This will cause Django to fall
back to using the system timezone. back to using the system timezone.
If Django doesn't set the ``TZ`` environment variable, it's up to you If Django doesn't set the ``TZ`` environment variable, it's up to you
to ensure your processes are running in the correct environment. to ensure your processes are running in the correct environment.

View File

@ -62,24 +62,22 @@ Arguments sent with this signal:
A dictionary of keyword arguments passed to A dictionary of keyword arguments passed to
:meth:`~django.db.models.Model.__init__`:. :meth:`~django.db.models.Model.__init__`:.
For example, the :doc:`tutorial </intro/tutorial01>` has this line: For example, the :doc:`tutorial </intro/tutorial01>` has this line::
.. code-block:: python
p = Poll(question="What's up?", pub_date=datetime.now()) p = Poll(question="What's up?", pub_date=datetime.now())
The arguments sent to a :data:`pre_init` handler would be: The arguments sent to a :data:`pre_init` handler would be:
========== =============================================================== ========== ===============================================================
Argument Value Argument Value
========== =============================================================== ========== ===============================================================
``sender`` ``Poll`` (the class itself) ``sender`` ``Poll`` (the class itself)
``args`` ``[]`` (an empty list because there were no positional ``args`` ``[]`` (an empty list because there were no positional
arguments passed to ``__init__``.) arguments passed to ``__init__``.)
``kwargs`` ``{'question': "What's up?", 'pub_date': datetime.now()}`` ``kwargs`` ``{'question': "What's up?", 'pub_date': datetime.now()}``
========== =============================================================== ========== ===============================================================
post_init post_init
--------- ---------
@ -269,12 +267,11 @@ Arguments sent with this signal:
The database alias being used. The database alias being used.
For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled
like this: like this::
.. code-block:: python
class Topping(models.Model): class Topping(models.Model):
# ... # ...
pass
class Pizza(models.Model): class Pizza(models.Model):
# ... # ...
@ -282,62 +279,58 @@ like this:
If we would do something like this: If we would do something like this:
.. code-block:: python
>>> p = Pizza.object.create(...) >>> p = Pizza.object.create(...)
>>> t = Topping.objects.create(...) >>> t = Topping.objects.create(...)
>>> p.toppings.add(t) >>> p.toppings.add(t)
the arguments sent to a :data:`m2m_changed` handler would be: the arguments sent to a :data:`m2m_changed` handler would be:
============== ============================================================ ============== ============================================================
Argument Value Argument Value
============== ============================================================ ============== ============================================================
``sender`` ``Pizza.toppings.through`` (the intermediate m2m class) ``sender`` ``Pizza.toppings.through`` (the intermediate m2m class)
``instance`` ``p`` (the ``Pizza`` instance being modified) ``instance`` ``p`` (the ``Pizza`` instance being modified)
``action`` ``"pre_add"`` (followed by a separate signal with ``"post_add"``) ``action`` ``"pre_add"`` (followed by a separate signal with ``"post_add"``)
``reverse`` ``False`` (``Pizza`` contains the :class:`ManyToManyField`, ``reverse`` ``False`` (``Pizza`` contains the :class:`ManyToManyField`,
so this call modifies the forward relation) so this call modifies the forward relation)
``model`` ``Topping`` (the class of the objects added to the ``model`` ``Topping`` (the class of the objects added to the
``Pizza``) ``Pizza``)
``pk_set`` ``[t.id]`` (since only ``Topping t`` was added to the relation) ``pk_set`` ``[t.id]`` (since only ``Topping t`` was added to the relation)
``using`` ``"default"`` (since the default router sends writes here) ``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================ ============== ============================================================
And if we would then do something like this: And if we would then do something like this::
.. code-block:: python
>>> t.pizza_set.remove(p) >>> t.pizza_set.remove(p)
the arguments sent to a :data:`m2m_changed` handler would be: the arguments sent to a :data:`m2m_changed` handler would be:
============== ============================================================ ============== ============================================================
Argument Value Argument Value
============== ============================================================ ============== ============================================================
``sender`` ``Pizza.toppings.through`` (the intermediate m2m class) ``sender`` ``Pizza.toppings.through`` (the intermediate m2m class)
``instance`` ``t`` (the ``Topping`` instance being modified) ``instance`` ``t`` (the ``Topping`` instance being modified)
``action`` ``"pre_remove"`` (followed by a separate signal with ``"post_remove"``) ``action`` ``"pre_remove"`` (followed by a separate signal with ``"post_remove"``)
``reverse`` ``True`` (``Pizza`` contains the :class:`ManyToManyField`, ``reverse`` ``True`` (``Pizza`` contains the :class:`ManyToManyField`,
so this call modifies the reverse relation) so this call modifies the reverse relation)
``model`` ``Pizza`` (the class of the objects removed from the ``model`` ``Pizza`` (the class of the objects removed from the
``Topping``) ``Topping``)
``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the ``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the
relation) relation)
``using`` ``"default"`` (since the default router sends writes here) ``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================ ============== ============================================================
class_prepared class_prepared
-------------- --------------

View File

@ -193,14 +193,14 @@ final byte stream that can be served to the client.
There are three circumstances under which a TemplateResponse will be There are three circumstances under which a TemplateResponse will be
rendered: rendered:
* When the TemplateResponse instance is explicitly rendered, using * When the TemplateResponse instance is explicitly rendered, using
the :meth:`SimpleTemplateResponse.render()` method. the :meth:`SimpleTemplateResponse.render()` method.
* When the content of the response is explicitly set by assigning * When the content of the response is explicitly set by assigning
:attr:`response.content`. :attr:`response.content`.
* After passing through template response middleware, but before * After passing through template response middleware, but before
passing through response middleware. passing through response middleware.
A TemplateResponse can only be rendered once. The first call to A TemplateResponse can only be rendered once. The first call to
:meth:`SimpleTemplateResponse.render` sets the content of the :meth:`SimpleTemplateResponse.render` sets the content of the

View File

@ -56,9 +56,9 @@ Using the template system
Using the template system in Python is a two-step process: Using the template system in Python is a two-step process:
* First, you compile the raw template code into a ``Template`` object. * First, you compile the raw template code into a ``Template`` object.
* Then, you call the ``render()`` method of the ``Template`` object with a * Then, you call the ``render()`` method of the ``Template`` object with a
given context. given context.
Compiling a string Compiling a string
------------------ ------------------
@ -91,11 +91,11 @@ multiple contexts -- with it. The ``Context`` class lives at
:class:`django.template.Context`, and the constructor takes two (optional) :class:`django.template.Context`, and the constructor takes two (optional)
arguments: arguments:
* A dictionary mapping variable names to variable values. * A dictionary mapping variable names to variable values.
* The name of the current application. This application name is used * The name of the current application. This application name is used
to help :ref:`resolve namespaced URLs<topics-http-reversing-url-namespaces>`. to help :ref:`resolve namespaced URLs<topics-http-reversing-url-namespaces>`.
If you're not using namespaced URLs, you can ignore this argument. If you're not using namespaced URLs, you can ignore this argument.
Call the ``Template`` object's ``render()`` method with the context to "fill" the Call the ``Template`` object's ``render()`` method with the context to "fill" the
template:: template::
@ -118,9 +118,9 @@ Dots have a special meaning in template rendering. A dot in a variable name
signifies a **lookup**. Specifically, when the template system encounters a signifies a **lookup**. Specifically, when the template system encounters a
dot in a variable name, it tries the following lookups, in this order: dot in a variable name, it tries the following lookups, in this order:
* Dictionary lookup. Example: ``foo["bar"]`` * Dictionary lookup. Example: ``foo["bar"]``
* Attribute lookup. Example: ``foo.bar`` * Attribute lookup. Example: ``foo.bar``
* List-index lookup. Example: ``foo[bar]`` * List-index lookup. Example: ``foo[bar]``
The template system uses the first lookup type that works. It's short-circuit The template system uses the first lookup type that works. It's short-circuit
logic. Here are a few examples:: logic. Here are a few examples::
@ -161,69 +161,69 @@ it. Example::
Callable variables are slightly more complex than variables which only require Callable variables are slightly more complex than variables which only require
straight lookups. Here are some things to keep in mind: straight lookups. Here are some things to keep in mind:
* If the variable raises an exception when called, the exception will be * If the variable raises an exception when called, the exception will be
propagated, unless the exception has an attribute propagated, unless the exception has an attribute
``silent_variable_failure`` whose value is ``True``. If the exception ``silent_variable_failure`` whose value is ``True``. If the exception
*does* have a ``silent_variable_failure`` attribute whose value is *does* have a ``silent_variable_failure`` attribute whose value is
``True``, the variable will render as an empty string. Example:: ``True``, the variable will render as an empty string. Example::
>>> t = Template("My name is {{ person.first_name }}.") >>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3: >>> class PersonClass3:
... def first_name(self): ... def first_name(self):
... raise AssertionError("foo") ... raise AssertionError("foo")
>>> p = PersonClass3() >>> p = PersonClass3()
>>> t.render(Context({"person": p})) >>> t.render(Context({"person": p}))
Traceback (most recent call last): Traceback (most recent call last):
... ...
AssertionError: foo AssertionError: foo
>>> class SilentAssertionError(Exception): >>> class SilentAssertionError(Exception):
... silent_variable_failure = True ... silent_variable_failure = True
>>> class PersonClass4: >>> class PersonClass4:
... def first_name(self): ... def first_name(self):
... raise SilentAssertionError ... raise SilentAssertionError
>>> p = PersonClass4() >>> p = PersonClass4()
>>> t.render(Context({"person": p})) >>> t.render(Context({"person": p}))
"My name is ." "My name is ."
Note that :exc:`django.core.exceptions.ObjectDoesNotExist`, which is the Note that :exc:`django.core.exceptions.ObjectDoesNotExist`, which is the
base class for all Django database API ``DoesNotExist`` exceptions, has base class for all Django database API ``DoesNotExist`` exceptions, has
``silent_variable_failure = True``. So if you're using Django templates ``silent_variable_failure = True``. So if you're using Django templates
with Django model objects, any ``DoesNotExist`` exception will fail with Django model objects, any ``DoesNotExist`` exception will fail
silently. silently.
* A variable can only be called if it has no required arguments. Otherwise, * A variable can only be called if it has no required arguments. Otherwise,
the system will return an empty string. the system will return an empty string.
* Obviously, there can be side effects when calling some variables, and * Obviously, there can be side effects when calling some variables, and
it'd be either foolish or a security hole to allow the template system it'd be either foolish or a security hole to allow the template system
to access them. to access them.
A good example is the :meth:`~django.db.models.Model.delete` method on A good example is the :meth:`~django.db.models.Model.delete` method on
each Django model object. The template system shouldn't be allowed to do each Django model object. The template system shouldn't be allowed to do
something like this:: something like this::
I will now delete this valuable data. {{ data.delete }} I will now delete this valuable data. {{ data.delete }}
To prevent this, set an ``alters_data`` attribute on the callable To prevent this, set an ``alters_data`` attribute on the callable
variable. The template system won't call a variable if it has variable. The template system won't call a variable if it has
``alters_data=True`` set, and will instead replace the variable with ``alters_data=True`` set, and will instead replace the variable with
:setting:`TEMPLATE_STRING_IF_INVALID`, unconditionally. The :setting:`TEMPLATE_STRING_IF_INVALID`, unconditionally. The
dynamically-generated :meth:`~django.db.models.Model.delete` and dynamically-generated :meth:`~django.db.models.Model.delete` and
:meth:`~django.db.models.Model.save` methods on Django model objects get :meth:`~django.db.models.Model.save` methods on Django model objects get
``alters_data=True`` automatically. Example:: ``alters_data=True`` automatically. Example::
def sensitive_function(self): def sensitive_function(self):
self.database_record.delete() self.database_record.delete()
sensitive_function.alters_data = True sensitive_function.alters_data = True
* .. versionadded:: 1.4 * .. versionadded:: 1.4
Occasionally you may want to turn off this feature for other reasons, Occasionally you may want to turn off this feature for other reasons,
and tell the template system to leave a variable un-called no matter and tell the template system to leave a variable un-called no matter
what. To do so, set a ``do_not_call_in_templates`` attribute on the what. To do so, set a ``do_not_call_in_templates`` attribute on the
callable with the value ``True``. The template system then will act as callable with the value ``True``. The template system then will act as
if your variable is not callable (allowing you to access attributes of if your variable is not callable (allowing you to access attributes of
the callable, for example). the callable, for example).
.. _invalid-template-variables: .. _invalid-template-variables:
@ -427,13 +427,13 @@ django.contrib.auth.context_processors.auth
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain these three variables: ``RequestContext`` will contain these three variables:
* ``user`` -- An ``auth.User`` instance representing the currently * ``user`` -- An ``auth.User`` instance representing the currently
logged-in user (or an ``AnonymousUser`` instance, if the client isn't logged-in user (or an ``AnonymousUser`` instance, if the client isn't
logged in). logged in).
* ``perms`` -- An instance of * ``perms`` -- An instance of
``django.contrib.auth.context_processors.PermWrapper``, representing the ``django.contrib.auth.context_processors.PermWrapper``, representing the
permissions that the currently logged-in user has. permissions that the currently logged-in user has.
.. versionchanged:: 1.2 .. versionchanged:: 1.2
This context processor was moved in this release from This context processor was moved in this release from
@ -452,11 +452,11 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
:setting:`DEBUG` setting is set to ``True`` and the request's IP address :setting:`DEBUG` setting is set to ``True`` and the request's IP address
(``request.META['REMOTE_ADDR']``) is in the :setting:`INTERNAL_IPS` setting: (``request.META['REMOTE_ADDR']``) is in the :setting:`INTERNAL_IPS` setting:
* ``debug`` -- ``True``. You can use this in templates to test whether * ``debug`` -- ``True``. You can use this in templates to test whether
you're in :setting:`DEBUG` mode. you're in :setting:`DEBUG` mode.
* ``sql_queries`` -- A list of ``{'sql': ..., 'time': ...}`` dictionaries, * ``sql_queries`` -- A list of ``{'sql': ..., 'time': ...}`` dictionaries,
representing every SQL query that has happened so far during the request representing every SQL query that has happened so far during the request
and how long it took. The list is in order by query. and how long it took. The list is in order by query.
django.core.context_processors.i18n django.core.context_processors.i18n
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -464,9 +464,9 @@ django.core.context_processors.i18n
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain these two variables: ``RequestContext`` will contain these two variables:
* ``LANGUAGES`` -- The value of the :setting:`LANGUAGES` setting. * ``LANGUAGES`` -- The value of the :setting:`LANGUAGES` setting.
* ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise, * ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise,
the value of the :setting:`LANGUAGE_CODE` setting. the value of the :setting:`LANGUAGE_CODE` setting.
See :doc:`/topics/i18n/index` for more. See :doc:`/topics/i18n/index` for more.
@ -511,9 +511,9 @@ django.contrib.messages.context_processors.messages
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain a single additional variable: ``RequestContext`` will contain a single additional variable:
* ``messages`` -- A list of messages (as strings) that have been set * ``messages`` -- A list of messages (as strings) that have been set
via the user model (using ``user.message_set.create``) or through via the user model (using ``user.message_set.create``) or through
the :doc:`messages framework </ref/contrib/messages>`. the :doc:`messages framework </ref/contrib/messages>`.
.. versionadded:: 1.2 .. versionadded:: 1.2
This template context variable was previously supplied by the ``'auth'`` This template context variable was previously supplied by the ``'auth'``
@ -589,16 +589,16 @@ For example, if you call ``get_template('story_detail.html')`` and have the
above :setting:`TEMPLATE_DIRS` setting, here are the files Django will look for, above :setting:`TEMPLATE_DIRS` setting, here are the files Django will look for,
in order: in order:
* ``/home/html/templates/lawrence.com/story_detail.html`` * ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html`` * ``/home/html/templates/default/story_detail.html``
If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``, If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``,
here's what Django will look for: here's what Django will look for:
* ``/home/html/templates/lawrence.com/story_253_detail.html`` * ``/home/html/templates/lawrence.com/story_253_detail.html``
* ``/home/html/templates/default/story_253_detail.html`` * ``/home/html/templates/default/story_253_detail.html``
* ``/home/html/templates/lawrence.com/story_detail.html`` * ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html`` * ``/home/html/templates/default/story_detail.html``
When Django finds a template that exists, it stops looking. When Django finds a template that exists, it stops looking.
@ -628,8 +628,8 @@ To load a template that's within a subdirectory, just use a slash, like so::
Using the same :setting:`TEMPLATE_DIRS` setting from above, this example Using the same :setting:`TEMPLATE_DIRS` setting from above, this example
``get_template()`` call will attempt to load the following templates: ``get_template()`` call will attempt to load the following templates:
* ``/home/html/templates/lawrence.com/news/story_detail.html`` * ``/home/html/templates/lawrence.com/news/story_detail.html``
* ``/home/html/templates/default/news/story_detail.html`` * ``/home/html/templates/default/news/story_detail.html``
.. _template-loaders: .. _template-loaders:
@ -669,8 +669,8 @@ class. Here are the template loaders that come with Django:
...then ``get_template('foo.html')`` will look for templates in these ...then ``get_template('foo.html')`` will look for templates in these
directories, in this order: directories, in this order:
* ``/path/to/myproject/polls/templates/foo.html`` * ``/path/to/myproject/polls/templates/foo.html``
* ``/path/to/myproject/music/templates/foo.html`` * ``/path/to/myproject/music/templates/foo.html``
Note that the loader performs an optimization when it is first imported: It Note that the loader performs an optimization when it is first imported: It
caches a list of which :setting:`INSTALLED_APPS` packages have a caches a list of which :setting:`INSTALLED_APPS` packages have a
@ -739,15 +739,15 @@ The ``render_to_string`` shortcut takes one required argument --
and render (or a list of template names, in which case Django will use and render (or a list of template names, in which case Django will use
the first template in the list that exists) -- and two optional arguments: the first template in the list that exists) -- and two optional arguments:
dictionary dictionary
A dictionary to be used as variables and values for the A dictionary to be used as variables and values for the
template's context. This can also be passed as the second template's context. This can also be passed as the second
positional argument. positional argument.
context_instance context_instance
An instance of ``Context`` or a subclass (e.g., an instance of An instance of ``Context`` or a subclass (e.g., an instance of
``RequestContext``) to use as the template's context. This can ``RequestContext``) to use as the template's context. This can
also be passed as the third positional argument. also be passed as the third positional argument.
See also the :func:`~django.shortcuts.render_to_response()` shortcut, which See also the :func:`~django.shortcuts.render_to_response()` shortcut, which
calls ``render_to_string`` and feeds the result into an :class:`~django.http.HttpResponse` calls ``render_to_string`` and feeds the result into an :class:`~django.http.HttpResponse`

View File

@ -201,13 +201,13 @@ Signals that this template extends a parent template.
This tag can be used in two ways: This tag can be used in two ways:
* ``{% extends "base.html" %}`` (with quotes) uses the literal value * ``{% extends "base.html" %}`` (with quotes) uses the literal value
``"base.html"`` as the name of the parent template to extend. ``"base.html"`` as the name of the parent template to extend.
* ``{% extends variable %}`` uses the value of ``variable``. If the variable * ``{% extends variable %}`` uses the value of ``variable``. If the variable
evaluates to a string, Django will use that string as the name of the evaluates to a string, Django will use that string as the name of the
parent template. If the variable evaluates to a ``Template`` object, parent template. If the variable evaluates to a ``Template`` object,
Django will use that object as the parent template. Django will use that object as the parent template.
See :ref:`template-inheritance` for more information. See :ref:`template-inheritance` for more information.
@ -303,20 +303,20 @@ would display the keys and values of the dictionary::
The for loop sets a number of variables available within the loop: The for loop sets a number of variables available within the loop:
========================== =============================================== ========================== ===============================================
Variable Description Variable Description
========================== =============================================== ========================== ===============================================
``forloop.counter`` The current iteration of the loop (1-indexed) ``forloop.counter`` The current iteration of the loop (1-indexed)
``forloop.counter0`` The current iteration of the loop (0-indexed) ``forloop.counter0`` The current iteration of the loop (0-indexed)
``forloop.revcounter`` The number of iterations from the end of the ``forloop.revcounter`` The number of iterations from the end of the
loop (1-indexed) loop (1-indexed)
``forloop.revcounter0`` The number of iterations from the end of the ``forloop.revcounter0`` The number of iterations from the end of the
loop (0-indexed) loop (0-indexed)
``forloop.first`` True if this is the first time through the loop ``forloop.first`` True if this is the first time through the loop
``forloop.last`` True if this is the last time through the loop ``forloop.last`` True if this is the last time through the loop
``forloop.parentloop`` For nested loops, this is the loop "above" the ``forloop.parentloop`` For nested loops, this is the loop "above" the
current one current one
========================== =============================================== ========================== ===============================================
for ... empty for ... empty
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
@ -526,11 +526,11 @@ 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 expression is evaluated - that is, the precedence rules. The precedence of the
operators, from lowest to highest, is as follows: operators, from lowest to highest, is as follows:
* ``or`` * ``or``
* ``and`` * ``and``
* ``not`` * ``not``
* ``in`` * ``in``
* ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=`` * ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``
(This follows Python exactly). So, for example, the following complex (This follows Python exactly). So, for example, the following complex
:ttag:`if` tag: :ttag:`if` tag:
@ -660,14 +660,14 @@ the variable ``template_name``::
An included template is rendered with the context of the template that's An included template is rendered with the context of the template that's
including it. This example produces the output ``"Hello, John"``: including it. This example produces the output ``"Hello, John"``:
* Context: variable ``person`` is set to ``"john"``. * Context: variable ``person`` is set to ``"john"``.
* Template:: * Template::
{% include "name_snippet.html" %} {% include "name_snippet.html" %}
* The ``name_snippet.html`` template:: * The ``name_snippet.html`` template::
{{ greeting }}, {{ person|default:"friend" }}! {{ greeting }}, {{ person|default:"friend" }}!
.. versionchanged:: 1.3 .. versionchanged:: 1.3
Additional context and exclusive context. Additional context and exclusive context.
@ -771,14 +771,14 @@ is a list of people represented by dictionaries with ``first_name``,
...and you'd like to display a hierarchical list that is ordered by gender, ...and you'd like to display a hierarchical list that is ordered by gender,
like this: like this:
* Male: * Male:
* George Bush * George Bush
* Bill Clinton * Bill Clinton
* Female: * Female:
* Margaret Thatcher * Margaret Thatcher
* Condoleezza Rice * Condoleezza Rice
* Unknown: * Unknown:
* Pat Smith * Pat Smith
You can use the ``{% regroup %}`` tag to group the list of people by gender. You can use the ``{% regroup %}`` tag to group the list of people by gender.
The following snippet of template code would accomplish this:: The following snippet of template code would accomplish this::
@ -805,10 +805,10 @@ attribute and calling the result ``gender_list``.
``{% regroup %}`` produces a list (in this case, ``gender_list``) of ``{% regroup %}`` produces a list (in this case, ``gender_list``) of
**group objects**. Each group object has two attributes: **group objects**. Each group object has two attributes:
* ``grouper`` -- the item that was grouped by (e.g., the string "Male" or * ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
"Female"). "Female").
* ``list`` -- a list of all items in this group (e.g., a list of all people * ``list`` -- a list of all items in this group (e.g., a list of all people
with gender='Male'). with gender='Male').
Note that ``{% regroup %}`` does not order its input! Our example relies on Note that ``{% regroup %}`` does not order its input! Our example relies on
the fact that the ``people`` list was ordered by ``gender`` in the first place. the fact that the ``people`` list was ordered by ``gender`` in the first place.
@ -830,16 +830,16 @@ grouped together):
With this input for ``people``, the example ``{% regroup %}`` template code With this input for ``people``, the example ``{% regroup %}`` template code
above would result in the following output: above would result in the following output:
* Male: * Male:
* Bill Clinton * Bill Clinton
* Unknown: * Unknown:
* Pat Smith * Pat Smith
* Female: * Female:
* Margaret Thatcher * Margaret Thatcher
* Male: * Male:
* George Bush * George Bush
* Female: * Female:
* Condoleezza Rice * Condoleezza Rice
The easiest solution to this gotcha is to make sure in your view code that the The easiest solution to this gotcha is to make sure in your view code that the
data is ordered according to how you want to display it. data is ordered according to how you want to display it.
@ -959,18 +959,18 @@ bits used in template tags, you must use the ``{% templatetag %}`` tag.
The argument tells which template bit to output: The argument tells which template bit to output:
================== ======= ================== =======
Argument Outputs Argument Outputs
================== ======= ================== =======
``openblock`` ``{%`` ``openblock`` ``{%``
``closeblock`` ``%}`` ``closeblock`` ``%}``
``openvariable`` ``{{`` ``openvariable`` ``{{``
``closevariable`` ``}}`` ``closevariable`` ``}}``
``openbrace`` ``{`` ``openbrace`` ``{``
``closebrace`` ``}`` ``closebrace`` ``}``
``opencomment`` ``{#`` ``opencomment`` ``{#``
``closecomment`` ``#}`` ``closecomment`` ``#}``
================== ======= ================== =======
.. templatetag:: url .. templatetag:: url
@ -1250,75 +1250,75 @@ with some custom extensions.
Available format strings: Available format strings:
================ ======================================== ===================== ================ ======================================== =====================
Format character Description Example output Format character Description Example output
================ ======================================== ===================== ================ ======================================== =====================
a ``'a.m.'`` or ``'p.m.'`` (Note that ``'a.m.'`` a ``'a.m.'`` or ``'p.m.'`` (Note that ``'a.m.'``
this is slightly different than PHP's this is slightly different than PHP's
output, because this includes periods output, because this includes periods
to match Associated Press style.) to match Associated Press style.)
A ``'AM'`` or ``'PM'``. ``'AM'`` A ``'AM'`` or ``'PM'``. ``'AM'``
b Month, textual, 3 letters, lowercase. ``'jan'`` b Month, textual, 3 letters, lowercase. ``'jan'``
B Not implemented. B Not implemented.
c ISO 8601 format. (Note: unlike others ``2008-01-02T10:30:00.000123+02:00``, c ISO 8601 format. (Note: unlike others ``2008-01-02T10:30:00.000123+02:00``,
formatters, such as "Z", "O" or "r", or ``2008-01-02T10:30:00.000123`` if the datetime is naive formatters, such as "Z", "O" or "r", or ``2008-01-02T10:30:00.000123`` if the datetime is naive
the "c" formatter will not add timezone the "c" formatter will not add timezone
offset if value is a naive datetime offset if value is a naive datetime
(see :class:`datetime.tzinfo`). (see :class:`datetime.tzinfo`).
d Day of the month, 2 digits with ``'01'`` to ``'31'`` d Day of the month, 2 digits with ``'01'`` to ``'31'``
leading zeros. leading zeros.
D Day of the week, textual, 3 letters. ``'Fri'`` D Day of the week, textual, 3 letters. ``'Fri'``
E Month, locale specific alternative E Month, locale specific alternative
representation usually used for long representation usually used for long
date representation. ``'listopada'`` (for Polish locale, as opposed to ``'Listopad'``) date representation. ``'listopada'`` (for Polish locale, as opposed to ``'Listopad'``)
f Time, in 12-hour hours and minutes, ``'1'``, ``'1:30'`` f Time, in 12-hour hours and minutes, ``'1'``, ``'1:30'``
with minutes left off if they're zero. with minutes left off if they're zero.
Proprietary extension. Proprietary extension.
F Month, textual, long. ``'January'`` F Month, textual, long. ``'January'``
g Hour, 12-hour format without leading ``'1'`` to ``'12'`` g Hour, 12-hour format without leading ``'1'`` to ``'12'``
zeros. zeros.
G Hour, 24-hour format without leading ``'0'`` to ``'23'`` G Hour, 24-hour format without leading ``'0'`` to ``'23'``
zeros. zeros.
h Hour, 12-hour format. ``'01'`` to ``'12'`` h Hour, 12-hour format. ``'01'`` to ``'12'``
H Hour, 24-hour format. ``'00'`` to ``'23'`` H Hour, 24-hour format. ``'00'`` to ``'23'``
i Minutes. ``'00'`` to ``'59'`` i Minutes. ``'00'`` to ``'59'``
I Not implemented. I Not implemented.
j Day of the month without leading ``'1'`` to ``'31'`` j Day of the month without leading ``'1'`` to ``'31'``
zeros. zeros.
l Day of the week, textual, long. ``'Friday'`` l Day of the week, textual, long. ``'Friday'``
L Boolean for whether it's a leap year. ``True`` or ``False`` L Boolean for whether it's a leap year. ``True`` or ``False``
m Month, 2 digits with leading zeros. ``'01'`` to ``'12'`` m Month, 2 digits with leading zeros. ``'01'`` to ``'12'``
M Month, textual, 3 letters. ``'Jan'`` M Month, textual, 3 letters. ``'Jan'``
n Month without leading zeros. ``'1'`` to ``'12'`` n Month without leading zeros. ``'1'`` to ``'12'``
N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'`` N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'``
style. Proprietary extension. style. Proprietary extension.
O Difference to Greenwich time in hours. ``'+0200'`` O Difference to Greenwich time in hours. ``'+0200'``
P Time, in 12-hour hours, minutes and ``'1 a.m.'``, ``'1:30 p.m.'``, ``'midnight'``, ``'noon'``, ``'12:30 p.m.'`` P Time, in 12-hour hours, minutes and ``'1 a.m.'``, ``'1:30 p.m.'``, ``'midnight'``, ``'noon'``, ``'12:30 p.m.'``
'a.m.'/'p.m.', with minutes left off 'a.m.'/'p.m.', with minutes left off
if they're zero and the special-case if they're zero and the special-case
strings 'midnight' and 'noon' if strings 'midnight' and 'noon' if
appropriate. Proprietary extension. appropriate. Proprietary extension.
r :rfc:`2822` formatted date. ``'Thu, 21 Dec 2000 16:01:07 +0200'`` r :rfc:`2822` formatted date. ``'Thu, 21 Dec 2000 16:01:07 +0200'``
s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'`` s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'``
S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'`` S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'``
month, 2 characters. month, 2 characters.
t Number of days in the given month. ``28`` to ``31`` t Number of days in the given month. ``28`` to ``31``
T Time zone of this machine. ``'EST'``, ``'MDT'`` T Time zone of this machine. ``'EST'``, ``'MDT'``
u Microseconds. ``0`` to ``999999`` u Microseconds. ``0`` to ``999999``
U Seconds since the Unix Epoch U Seconds since the Unix Epoch
(January 1 1970 00:00:00 UTC). (January 1 1970 00:00:00 UTC).
w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday) w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday)
leading zeros. leading zeros.
W ISO-8601 week number of year, with ``1``, ``53`` W ISO-8601 week number of year, with ``1``, ``53``
weeks starting on Monday. weeks starting on Monday.
y Year, 2 digits. ``'99'`` y Year, 2 digits. ``'99'``
Y Year, 4 digits. ``'1999'`` Y Year, 4 digits. ``'1999'``
z Day of the year. ``0`` to ``365`` z Day of the year. ``0`` to ``365``
Z Time zone offset in seconds. The ``-43200`` to ``43200`` Z Time zone offset in seconds. The ``-43200`` to ``43200``
offset for timezones west of UTC is offset for timezones west of UTC is
always negative, and for those east of always negative, and for those east of
UTC is always positive. UTC is always positive.
================ ======================================== ===================== ================ ======================================== =====================
.. versionadded:: 1.2 .. versionadded:: 1.2
@ -1448,11 +1448,11 @@ escape
Escapes a string's HTML. Specifically, it makes these replacements: Escapes a string's HTML. Specifically, it makes these replacements:
* ``<`` is converted to ``&lt;`` * ``<`` is converted to ``&lt;``
* ``>`` is converted to ``&gt;`` * ``>`` is converted to ``&gt;``
* ``'`` (single quote) is converted to ``&#39;`` * ``'`` (single quote) is converted to ``&#39;``
* ``"`` (double quote) is converted to ``&quot;`` * ``"`` (double quote) is converted to ``&quot;``
* ``&`` is converted to ``&amp;`` * ``&`` is converted to ``&amp;``
The escaping is only applied when the string is output, so it does not matter The escaping is only applied when the string is output, so it does not matter
where in a chained sequence of filters you put ``escape``: it will always be where in a chained sequence of filters you put ``escape``: it will always be
@ -2320,9 +2320,9 @@ django.contrib.markup
A collection of template filters that implement these common markup languages: A collection of template filters that implement these common markup languages:
* Textile * Textile
* Markdown * Markdown
* reST (reStructuredText) * reST (reStructuredText)
See the :doc:`markup documentation </ref/contrib/markup>`. See the :doc:`markup documentation </ref/contrib/markup>`.

View File

@ -17,14 +17,14 @@ 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 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. able to store certain characters in the database, and information will be lost.
* MySQL users, refer to the `MySQL manual`_ (section 9.1.3.2 for MySQL 5.1) * 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. 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 users, refer to the `PostgreSQL manual`_ (section 21.2.2 in
PostgreSQL 8) for details on creating databases with the correct encoding. PostgreSQL 8) for details on creating databases with the correct encoding.
* SQLite users, there is nothing you need to do. SQLite always uses UTF-8 * SQLite users, there is nothing you need to do. SQLite always uses UTF-8
for internal encoding. for internal encoding.
.. _MySQL manual: http://dev.mysql.com/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 .. _PostgreSQL manual: http://www.postgresql.org/docs/8.2/static/multibyte.html#AEN24104
@ -106,35 +106,35 @@ Conversion functions
The ``django.utils.encoding`` module contains a few functions that are handy The ``django.utils.encoding`` module contains a few functions that are handy
for converting back and forth between Unicode and bytestrings. for converting back and forth between Unicode and bytestrings.
* ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')`` * ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
converts its input to a Unicode string. The ``encoding`` parameter converts its input to a Unicode string. The ``encoding`` parameter
specifies the input encoding. (For example, Django uses this internally specifies the input encoding. (For example, Django uses this internally
when processing form input data, which might not be UTF-8 encoded.) The when processing form input data, which might not be UTF-8 encoded.) The
``strings_only`` parameter, if set to True, will result in Python ``strings_only`` parameter, if set to True, will result in Python
numbers, booleans and ``None`` not being converted to a string (they keep numbers, booleans and ``None`` not being converted to a string (they keep
their original types). The ``errors`` parameter takes any of the values their original types). The ``errors`` parameter takes any of the values
that are accepted by Python's ``unicode()`` function for its error that are accepted by Python's ``unicode()`` function for its error
handling. handling.
If you pass ``smart_unicode()`` an object that has a ``__unicode__`` If you pass ``smart_unicode()`` an object that has a ``__unicode__``
method, it will use that method to do the conversion. method, it will use that method to do the conversion.
* ``force_unicode(s, encoding='utf-8', strings_only=False, * ``force_unicode(s, encoding='utf-8', strings_only=False,
errors='strict')`` is identical to ``smart_unicode()`` in almost all errors='strict')`` is identical to ``smart_unicode()`` in almost all
cases. The difference is when the first argument is a :ref:`lazy cases. The difference is when the first argument is a :ref:`lazy
translation <lazy-translations>` instance. While ``smart_unicode()`` translation <lazy-translations>` instance. While ``smart_unicode()``
preserves lazy translations, ``force_unicode()`` forces those objects to a preserves lazy translations, ``force_unicode()`` forces those objects to a
Unicode string (causing the translation to occur). Normally, you'll want Unicode string (causing the translation to occur). Normally, you'll want
to use ``smart_unicode()``. However, ``force_unicode()`` is useful in to use ``smart_unicode()``. However, ``force_unicode()`` is useful in
template tags and filters that absolutely *must* have a string to work template tags and filters that absolutely *must* have a string to work
with, not just something that can be converted to a string. with, not just something that can be converted to a string.
* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')`` * ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
is essentially the opposite of ``smart_unicode()``. It forces the first is essentially the opposite of ``smart_unicode()``. It forces the first
argument to a bytestring. The ``strings_only`` parameter has the same argument to a bytestring. The ``strings_only`` parameter has the same
behavior as for ``smart_unicode()`` and ``force_unicode()``. This is behavior as for ``smart_unicode()`` and ``force_unicode()``. This is
slightly different semantics from Python's builtin ``str()`` function, slightly different semantics from Python's builtin ``str()`` function,
but the difference is needed in a few places within Django's internals. but the difference is needed in a few places within Django's internals.
Normally, you'll only need to use ``smart_unicode()``. Call it as early as Normally, you'll only need to use ``smart_unicode()``. Call it as early as
possible on any input data that might be either Unicode or a bytestring, and possible on any input data that might be either Unicode or a bytestring, and
@ -152,13 +152,13 @@ URL from an IRI_ -- very loosely speaking, a URI_ that can contain Unicode
characters. Quoting and converting an IRI to URI can be a little tricky, so characters. Quoting and converting an IRI to URI can be a little tricky, so
Django provides some assistance. Django provides some assistance.
* The function ``django.utils.encoding.iri_to_uri()`` implements the * The function ``django.utils.encoding.iri_to_uri()`` implements the
conversion from IRI to URI as required by the specification (:rfc:`3987`). conversion from IRI to URI as required by the specification (:rfc:`3987`).
* The functions ``django.utils.http.urlquote()`` and * The functions ``django.utils.http.urlquote()`` and
``django.utils.http.urlquote_plus()`` are versions of Python's standard ``django.utils.http.urlquote_plus()`` are versions of Python's standard
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII ``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
characters. (The data is converted to UTF-8 prior to encoding.) characters. (The data is converted to UTF-8 prior to encoding.)
These two groups of functions have slightly different purposes, and it's These two groups of functions have slightly different purposes, and it's
important to keep them straight. Normally, you would use ``urlquote()`` on the important to keep them straight. Normally, you would use ``urlquote()`` on the
@ -295,14 +295,14 @@ Template tags and filters
A couple of tips to remember when writing your own template tags and filters: A couple of tips to remember when writing your own template tags and filters:
* Always return Unicode strings from a template tag's ``render()`` method * Always return Unicode strings from a template tag's ``render()`` method
and from template filters. and from template filters.
* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these * Use ``force_unicode()`` in preference to ``smart_unicode()`` in these
places. Tag rendering and filter calls occur as the template is being places. Tag rendering and filter calls occur as the template is being
rendered, so there is no advantage to postponing the conversion of lazy rendered, so there is no advantage to postponing the conversion of lazy
translation objects into strings. It's easier to work solely with Unicode translation objects into strings. It's easier to work solely with Unicode
strings at that point. strings at that point.
Email Email
===== =====

View File

@ -37,12 +37,12 @@ to distinguish caches by the ``Accept-language`` header.
This function patches the ``Cache-Control`` header by adding all keyword This function patches the ``Cache-Control`` header by adding all keyword
arguments to it. The transformation is as follows: arguments to it. The transformation is as follows:
* All keyword parameter names are turned to lowercase, and underscores * All keyword parameter names are turned to lowercase, and underscores
are converted to hyphens. are converted to hyphens.
* If the value of a parameter is ``True`` (exactly ``True``, not just a * If the value of a parameter is ``True`` (exactly ``True``, not just a
true value), only the parameter name is added to the header. true value), only the parameter name is added to the header.
* All other parameters are added with their value, after applying * All other parameters are added with their value, after applying
``str()`` to it. ``str()`` to it.
.. function:: get_max_age(response) .. function:: get_max_age(response)
@ -53,10 +53,10 @@ to distinguish caches by the ``Accept-language`` header.
Adds some useful headers to the given ``HttpResponse`` object: Adds some useful headers to the given ``HttpResponse`` object:
* ``ETag`` * ``ETag``
* ``Last-Modified`` * ``Last-Modified``
* ``Expires`` * ``Expires``
* ``Cache-Control`` * ``Cache-Control``
Each header is only added if it isn't already set. Each header is only added if it isn't already set.
@ -553,8 +553,8 @@ For a complete discussion on the usage of the following see the
Returns selected language's BiDi layout: Returns selected language's BiDi layout:
* ``False`` = left-to-right layout * ``False`` = left-to-right layout
* ``True`` = right-to-left layout * ``True`` = right-to-left layout
.. function:: get_language_from_request(request) .. function:: get_language_from_request(request)

View File

@ -44,46 +44,46 @@ etc., to improve developers' quality of life.
The new features and changes introduced in 0.95 include: The new features and changes introduced in 0.95 include:
* Django now uses a more consistent and natural filtering interface for * Django now uses a more consistent and natural filtering interface for
retrieving objects from the database. retrieving objects from the database.
* User-defined models, functions and constants now appear in the module * User-defined models, functions and constants now appear in the module
namespace they were defined in. (Previously everything was magically namespace they were defined in. (Previously everything was magically
transferred to the django.models.* namespace.) transferred to the django.models.* namespace.)
* Some optional applications, such as the FlatPage, Sites and Redirects * Some optional applications, such as the FlatPage, Sites and Redirects
apps, have been decoupled and moved into django.contrib. If you don't apps, have been decoupled and moved into django.contrib. If you don't
want to use these applications, you no longer have to install their want to use these applications, you no longer have to install their
database tables. database tables.
* Django now has support for managing database transactions. * Django now has support for managing database transactions.
* We've added the ability to write custom authentication and authorization * We've added the ability to write custom authentication and authorization
backends for authenticating users against alternate systems, such as backends for authenticating users against alternate systems, such as
LDAP. LDAP.
* We've made it easier to add custom table-level functions to models, * We've made it easier to add custom table-level functions to models,
through a new "Manager" API. through a new "Manager" API.
* It's now possible to use Django without a database. This simply means * It's now possible to use Django without a database. This simply means
that the framework no longer requires you to have a working database set that the framework no longer requires you to have a working database set
up just to serve dynamic pages. In other words, you can just use up just to serve dynamic pages. In other words, you can just use
URLconfs/views on their own. Previously, the framework required that a URLconfs/views on their own. Previously, the framework required that a
database be configured, regardless of whether you actually used it. database be configured, regardless of whether you actually used it.
* It's now more explicit and natural to override save() and delete() * It's now more explicit and natural to override save() and delete()
methods on models, rather than needing to hook into the pre_save() and methods on models, rather than needing to hook into the pre_save() and
post_save() method hooks. post_save() method hooks.
* Individual pieces of the framework now can be configured without * Individual pieces of the framework now can be configured without
requiring the setting of an environment variable. This permits use of, requiring the setting of an environment variable. This permits use of,
for example, the Django templating system inside other applications. for example, the Django templating system inside other applications.
* More and more parts of the framework have been internationalized, as * More and more parts of the framework have been internationalized, as
we've expanded internationalization (i18n) support. The Django we've expanded internationalization (i18n) support. The Django
codebase, including code and templates, has now been translated, at least codebase, including code and templates, has now been translated, at least
in part, into 31 languages. From Arabic to Chinese to Hungarian to Welsh, in part, into 31 languages. From Arabic to Chinese to Hungarian to Welsh,
it is now possible to use Django's admin site in your native language. it is now possible to use Django's admin site in your native language.
The number of changes required to port from 0.91-compatible code to the 0.95 The number of changes required to port from 0.91-compatible code to the 0.95
code base are significant in some cases. However, they are, for the most part, code base are significant in some cases. However, they are, for the most part,

View File

@ -72,13 +72,13 @@ to raise an error message about modifying non-existent constraints.
If you need to work around this, there are two methods available: If you need to work around this, there are two methods available:
1. Redirect the output of ``manage.py`` to a file, and edit the 1. Redirect the output of ``manage.py`` to a file, and edit the
generated SQL to use the correct constraint names before generated SQL to use the correct constraint names before
executing it. executing it.
2. Examine the output of ``manage.py sqlall`` to see the new-style 2. Examine the output of ``manage.py sqlall`` to see the new-style
constraint names, and use that as a guide to rename existing constraint names, and use that as a guide to rename existing
constraints in your database. constraints in your database.
Name changes in ``manage.py`` Name changes in ``manage.py``
----------------------------- -----------------------------
@ -86,16 +86,16 @@ Name changes in ``manage.py``
A few of the options to ``manage.py`` have changed with the addition of fixture A few of the options to ``manage.py`` have changed with the addition of fixture
support: support:
* There are new ``dumpdata`` and ``loaddata`` commands which, as * There are new ``dumpdata`` and ``loaddata`` commands which, as
you might expect, will dump and load data to/from the you might expect, will dump and load data to/from the
database. These commands can operate against any of Django's database. These commands can operate against any of Django's
supported serialization formats. supported serialization formats.
* The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to * The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to
emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for
other custom SQL -- views, stored procedures, etc.). other custom SQL -- views, stored procedures, etc.).
* The vestigial ``install`` command has been removed. Use ``syncdb``. * The vestigial ``install`` command has been removed. Use ``syncdb``.
Backslash escaping changed Backslash escaping changed
-------------------------- --------------------------
@ -142,23 +142,23 @@ deprecate and remove the old system.
There are three elements to this transition: There are three elements to this transition:
* We've copied the current ``django.forms`` to * We've copied the current ``django.forms`` to
``django.oldforms``. This allows you to upgrade your code *now* ``django.oldforms``. This allows you to upgrade your code *now*
rather than waiting for the backwards-incompatible change and rather than waiting for the backwards-incompatible change and
rushing to fix your code after the fact. Just change your rushing to fix your code after the fact. Just change your
import statements like this:: import statements like this::
from django import forms # 0.95-style from django import forms # 0.95-style
from django import oldforms as forms # 0.96-style from django import oldforms as forms # 0.96-style
* The next official release of Django will move the current * The next official release of Django will move the current
``django.newforms`` to ``django.forms``. This will be a ``django.newforms`` to ``django.forms``. This will be a
backwards-incompatible change, and anyone still using the old backwards-incompatible change, and anyone still using the old
version of ``django.forms`` at that time will need to change version of ``django.forms`` at that time will need to change
their import statements as described above. their import statements as described above.
* The next release after that will completely remove * The next release after that will completely remove
``django.oldforms``. ``django.oldforms``.
Although the ``newforms`` library will continue to evolve, it's ready for use Although the ``newforms`` library will continue to evolve, it's ready for use
for most common cases. We recommend that anyone new to form handling skip the for most common cases. We recommend that anyone new to form handling skip the
@ -242,21 +242,21 @@ Since 0.95, a number of people have stepped forward and taken a major
new role in Django's development. We'd like to thank these people for new role in Django's development. We'd like to thank these people for
all their hard work: all their hard work:
* Russell Keith-Magee and Malcolm Tredinnick for their major code * Russell Keith-Magee and Malcolm Tredinnick for their major code
contributions. This release wouldn't have been possible without them. contributions. This release wouldn't have been possible without them.
* Our new release manager, James Bennett, for his work in getting out * Our new release manager, James Bennett, for his work in getting out
0.95.1, 0.96, and (hopefully) future release. 0.95.1, 0.96, and (hopefully) future release.
* Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill, * Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill,
Michael Radziej, and Gary Wilson. They agreed to take on the monumental Michael Radziej, and Gary Wilson. They agreed to take on the monumental
task of wrangling our tickets into nicely cataloged submission. Figuring task of wrangling our tickets into nicely cataloged submission. Figuring
out what to work on is now about a million times easier; thanks again, out what to work on is now about a million times easier; thanks again,
guys. guys.
* Everyone who submitted a bug report, patch or ticket comment. We can't * Everyone who submitted a bug report, patch or ticket comment. We can't
possibly thank everyone by name -- over 200 developers submitted patches possibly thank everyone by name -- over 200 developers submitted patches
that went into 0.96 -- but everyone who's contributed to Django is listed that went into 0.96 -- but everyone who's contributed to Django is listed
in AUTHORS_. in AUTHORS_.
.. _AUTHORS: http://code.djangoproject.com/browser/django/trunk/AUTHORS .. _AUTHORS: http://code.djangoproject.com/browser/django/trunk/AUTHORS

View File

@ -562,17 +562,17 @@ following, replacing ``<app>`` in the code below with each app's name:
Notes: Notes:
1. It's important that you remember to use XML format in the first step of 1. It's important that you remember to use XML format in the first step of
this process. We are exploiting a feature of the XML data dumps that makes this process. We are exploiting a feature of the XML data dumps that makes
porting floats to decimals with SQLite possible. porting floats to decimals with SQLite possible.
2. In the second step you will be asked to confirm that you are prepared to 2. In the second step you will be asked to confirm that you are prepared to
lose the data for the application(s) in question. Say yes; we'll restore lose the data for the application(s) in question. Say yes; we'll restore
this data in the third step, of course. this data in the third step, of course.
3. ``DecimalField`` is not used in any of the apps shipped with Django prior 3. ``DecimalField`` is not used in any of the apps shipped with Django prior
to this change being made, so you do not need to worry about performing to this change being made, so you do not need to worry about performing
this procedure for any of the standard Django models. this procedure for any of the standard Django models.
If something goes wrong in the above process, just copy your backed up If something goes wrong in the above process, just copy your backed up
database file over the original file and start again. database file over the original file and start again.
@ -717,13 +717,13 @@ a sequence of tuples.
To update your code: To update your code:
1. Use :class:`django.utils.datastructures.SortedDict` wherever you were 1. Use :class:`django.utils.datastructures.SortedDict` wherever you were
using ``django.newforms.forms.SortedDictFromList``. using ``django.newforms.forms.SortedDictFromList``.
2. Because :meth:`django.utils.datastructures.SortedDict.copy` doesn't 2. Because :meth:`django.utils.datastructures.SortedDict.copy` doesn't
return a deepcopy as ``SortedDictFromList.copy()`` did, you will need return a deepcopy as ``SortedDictFromList.copy()`` did, you will need
to update your code if you were relying on a deepcopy. Do this by using to update your code if you were relying on a deepcopy. Do this by using
``copy.deepcopy`` directly. ``copy.deepcopy`` directly.
Database backend functions Database backend functions
-------------------------- --------------------------

View File

@ -134,7 +134,7 @@ Django team by trying out the alpha codebase in a safe test environment and
reporting any bugs or issues you encounter. The Django ticket tracker is the reporting any bugs or issues you encounter. The Django ticket tracker is the
central place to search for open issues: central place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem you're Please open new tickets if no existing ticket corresponds to a problem you're
running into. running into.
@ -142,7 +142,7 @@ running into.
Additionally, discussion of Django development, including progress toward the Additionally, discussion of Django development, including progress toward the
1.1 release, takes place daily on the django-developers mailing list: 1.1 release, takes place daily on the django-developers mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -151,7 +151,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -104,15 +104,15 @@ Testing improvements
A couple of small but very useful improvements have been made to the A couple of small but very useful improvements have been made to the
:doc:`testing framework </topics/testing>`: :doc:`testing framework </topics/testing>`:
* The test :class:`Client` now can automatically follow redirects with the * The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This ``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler. makes testing views that issue redirects simpler.
* It's now easier to get at the template context in the response returned * It's now easier to get at the template context in the response returned
the test client: you'll simply access the context as the test client: you'll simply access the context as
``request.context[key]``. The old way, which treats ``request.context`` ``request.context[key]``. The old way, which treats ``request.context``
as a list of contexts, one for each rendered template, is still as a list of contexts, one for each rendered template, is still
available if you need it. available if you need it.
Conditional view processing Conditional view processing
--------------------------- ---------------------------
@ -129,30 +129,30 @@ Other improvements
Finally, a grab-bag of other neat features made their way into this beta Finally, a grab-bag of other neat features made their way into this beta
release, including: release, including:
* The :djadmin:`dumpdata` management command now accepts individual * The :djadmin:`dumpdata` management command now accepts individual
model names as arguments, allowing you to export the data just from model names as arguments, allowing you to export the data just from
particular models. particular models.
* There's a new :tfilter:`safeseq` template filter which works just like * There's a new :tfilter:`safeseq` template filter which works just like
:tfilter:`safe` for lists, marking each item in the list as safe. :tfilter:`safe` for lists, marking each item in the list as safe.
* :doc:`Cache backends </topics/cache>` now support ``incr()`` and * :doc:`Cache backends </topics/cache>` now support ``incr()`` and
``decr()`` commands to increment and decrement the value of a cache key. ``decr()`` commands to increment and decrement the value of a cache key.
On cache backends that support atomic increment/decrement -- most On cache backends that support atomic increment/decrement -- most
notably, the memcached backend -- these operations will be atomic, and notably, the memcached backend -- these operations will be atomic, and
quite fast. quite fast.
* Django now can :doc:`easily delegate authentication to the Web server * Django now can :doc:`easily delegate authentication to the Web server
</howto/auth-remote-user>` via a new authentication backend that supports </howto/auth-remote-user>` via a new authentication backend that supports
the standard ``REMOTE_USER`` environment variable used for this purpose. the standard ``REMOTE_USER`` environment variable used for this purpose.
* There's a new :func:`django.shortcuts.redirect` function that makes it * There's a new :func:`django.shortcuts.redirect` function that makes it
easier to issue redirects given an object, a view name, or a URL. easier to issue redirects given an object, a view name, or a URL.
* The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL * The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL
autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific
feature, that can make certain read-heavy applications a good deal feature, that can make certain read-heavy applications a good deal
faster. faster.
The Django 1.1 roadmap The Django 1.1 roadmap
====================== ======================
@ -179,7 +179,7 @@ Django team by trying out the beta codebase in a safe test environment and
reporting any bugs or issues you encounter. The Django ticket tracker is the reporting any bugs or issues you encounter. The Django ticket tracker is the
central place to search for open issues: central place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem you're Please open new tickets if no existing ticket corresponds to a problem you're
running into. running into.
@ -187,7 +187,7 @@ running into.
Additionally, discussion of Django development, including progress toward the Additionally, discussion of Django development, including progress toward the
1.1 release, takes place daily on the django-developers mailing list: 1.1 release, takes place daily on the django-developers mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -196,7 +196,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -84,7 +84,7 @@ release candidate in a safe testing environment and reporting any bugs
or issues you encounter. The Django ticket tracker is the central or issues you encounter. The Django ticket tracker is the central
place to search for open issues: place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open a new ticket only if no existing ticket corresponds to a Please open a new ticket only if no existing ticket corresponds to a
problem you're running into. problem you're running into.
@ -93,7 +93,7 @@ Additionally, discussion of Django development, including progress
toward the 1.1 release, takes place daily on the django-developers toward the 1.1 release, takes place daily on the django-developers
mailing list: mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -102,7 +102,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -28,14 +28,14 @@ token's presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis: requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using * Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest. XMLHttpRequest.
* Browsers have strict same-origin policies regarding * Browsers have strict same-origin policies regarding
XMLHttpRequest. XMLHttpRequest.
* In the context of a browser, the only way that a custom header * In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest. of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header. that appeared to be AJAX on the basis of the X-Requested-With header.

View File

@ -93,13 +93,13 @@ other than raise a ``DeprecationWarning``.
If you've been relying on this middleware, the easiest upgrade path is: If you've been relying on this middleware, the easiest upgrade path is:
* Examine `the code as it existed before it was removed`__. * Examine `the code as it existed before it was removed`__.
* Verify that it works correctly with your upstream proxy, modifying * Verify that it works correctly with your upstream proxy, modifying
it to support your particular proxy (if necessary). it to support your particular proxy (if necessary).
* Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a * Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a
piece of middleware in your own project. piece of middleware in your own project.
__ http://code.djangoproject.com/browser/django/trunk/django/middleware/http.py?rev=11000#L33 __ http://code.djangoproject.com/browser/django/trunk/django/middleware/http.py?rev=11000#L33
@ -157,14 +157,14 @@ Features deprecated in 1.1
One feature has been marked as deprecated in Django 1.1: One feature has been marked as deprecated in Django 1.1:
* You should no longer use ``AdminSite.root()`` to register that admin * You should no longer use ``AdminSite.root()`` to register that admin
views. That is, if your URLconf contains the line:: views. That is, if your URLconf contains the line::
(r'^admin/(.*)', admin.site.root), (r'^admin/(.*)', admin.site.root),
You should change it to read:: You should change it to read::
(r'^admin/', include(admin.site.urls)), (r'^admin/', include(admin.site.urls)),
You should begin to remove use of this feature from your code immediately. You should begin to remove use of this feature from your code immediately.
@ -289,15 +289,15 @@ Test client improvements
A couple of small -- but highly useful -- improvements have been made to the A couple of small -- but highly useful -- improvements have been made to the
test client: test client:
* The test :class:`Client` now can automatically follow redirects with the * The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This ``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler. makes testing views that issue redirects simpler.
* It's now easier to get at the template context in the response returned * It's now easier to get at the template context in the response returned
the test client: you'll simply access the context as the test client: you'll simply access the context as
``request.context[key]``. The old way, which treats ``request.context`` as ``request.context[key]``. The old way, which treats ``request.context`` as
a list of contexts, one for each rendered template in the inheritance a list of contexts, one for each rendered template in the inheritance
chain, is still available if you need it. chain, is still available if you need it.
New admin features New admin features
------------------ ------------------
@ -352,16 +352,16 @@ GeoDjango
In Django 1.1, GeoDjango_ (i.e. ``django.contrib.gis``) has several new In Django 1.1, GeoDjango_ (i.e. ``django.contrib.gis``) has several new
features: features:
* Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial * Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial
backend. backend.
* Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``) * Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``)
and ``F`` expressions. and ``F`` expressions.
* New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and * New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and
``snap_to_grid``. ``snap_to_grid``.
* A new list interface methods for ``GEOSGeometry`` objects. * A new list interface methods for ``GEOSGeometry`` objects.
For more details, see the `GeoDjango documentation`_. For more details, see the `GeoDjango documentation`_.
@ -446,7 +446,7 @@ the weary! If you'd like to help, discussion of Django development, including
progress toward the 1.2 release, takes place daily on the django-developers progress toward the 1.2 release, takes place daily on the django-developers
mailing list: mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. Feel free to ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. Feel free to
join the discussions! join the discussions!
@ -454,7 +454,7 @@ join the discussions!
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -26,28 +26,28 @@ There have been large changes to the way that CSRF protection works, detailed in
:doc:`the CSRF documentation </ref/contrib/csrf>`. The following are the major :doc:`the CSRF documentation </ref/contrib/csrf>`. The following are the major
changes that developers must be aware of: changes that developers must be aware of:
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and
**will be removed completely in Django 1.4**, in favor of a template tag that **will be removed completely in Django 1.4**, in favor of a template tag that
should be inserted into forms. should be inserted into forms.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This * All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the ``csrf_token`` template tag in the template, so if you requires the use of the ``csrf_token`` template tag in the template, so if you
have used custom templates for contrib views, you MUST READ THE UPGRADE have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates. INSTRUCTIONS to fix those templates.
.. admonition:: Documentation removed .. admonition:: Documentation removed
The upgrade notes have been removed in current Django docs. Please refer The upgrade notes have been removed in current Django docs. Please refer
to the docs for Django 1.3 or older to find these instructions. to the docs for Django 1.3 or older to find these instructions.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by * ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
default. This turns on CSRF protection by default, so that views that accept default. This turns on CSRF protection by default, so that views that accept
POST requests need to be written to work with the middleware. Instructions POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs. on how to do this are found in the CSRF docs.
* CSRF-related code has moved from ``contrib`` to ``core`` (with * CSRF-related code has moved from ``contrib`` to ``core`` (with
backwards compatible imports in the old locations, which are backwards compatible imports in the old locations, which are
deprecated). deprecated).
:ttag:`if` tag changes :ttag:`if` tag changes
---------------------- ----------------------
@ -70,18 +70,18 @@ If you used ``LazyObject`` in your own code, and implemented the
``get_all_members()`` method for wrapped objects, you need to make the following ``get_all_members()`` method for wrapped objects, you need to make the following
changes: changes:
* If your class does not have special requirements for introspection (i.e. you * If your class does not have special requirements for introspection (i.e. you
have not implemented ``__getattr__()`` or other methods that allow for have not implemented ``__getattr__()`` or other methods that allow for
attributes not discoverable by normal mechanisms), you can simply remove the attributes not discoverable by normal mechanisms), you can simply remove the
``get_all_members()`` method. The default implementation on ``LazyObject`` ``get_all_members()`` method. The default implementation on ``LazyObject``
will do the right thing. will do the right thing.
* If you have more complex requirements for introspection, first rename the * If you have more complex requirements for introspection, first rename the
``get_all_members()`` method to ``__dir__()``. This is the standard method, ``get_all_members()`` method to ``__dir__()``. This is the standard method,
from Python 2.6 onwards, for supporting introspection. If you are require from Python 2.6 onwards, for supporting introspection. If you are require
support for Python < 2.6, add the following code to the class:: support for Python < 2.6, add the following code to the class::
__members__ = property(lambda self: self.__dir__()) __members__ = property(lambda self: self.__dir__())
``__dict__`` on Model instances ``__dict__`` on Model instances
------------------------------- -------------------------------
@ -282,20 +282,20 @@ The sample settings given previously would now be stored using::
This affects the following settings: This affects the following settings:
========================================= ========================== ========================================= ==========================
Old setting New Setting Old setting New Setting
========================================= ========================== ========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE` :setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST` :setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME` :setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS` :setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD` :setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT` :setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER` :setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET` :setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION` :setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME` :setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ========================== ========================================= ==========================
These changes are also required if you have manually created a database These changes are also required if you have manually created a database
connection using ``DatabaseWrapper()`` from your database backend of choice. connection using ``DatabaseWrapper()`` from your database backend of choice.
@ -367,9 +367,9 @@ or, when directly formatting a date value::
The same applies to the globals found in ``django.forms.fields``: The same applies to the globals found in ``django.forms.fields``:
* ``DEFAULT_DATE_INPUT_FORMATS`` * ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS`` * ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_FORMATS`` * ``DEFAULT_DATETIME_INPUT_FORMATS``
Use ``django.utils.formats.get_format()`` to get the appropriate formats. Use ``django.utils.formats.get_format()`` to get the appropriate formats.
@ -559,7 +559,7 @@ Django team by trying out the alpha codebase in a safe test environment and
reporting any bugs or issues you encounter. The Django ticket tracker is the reporting any bugs or issues you encounter. The Django ticket tracker is the
central place to search for open issues: central place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem you're Please open new tickets if no existing ticket corresponds to a problem you're
running into. running into.
@ -567,7 +567,7 @@ running into.
Additionally, discussion of Django development, including progress toward the Additionally, discussion of Django development, including progress toward the
1.2 release, takes place daily on the django-developers mailing list: 1.2 release, takes place daily on the django-developers mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -576,7 +576,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -143,7 +143,7 @@ codebase in a safe test environment and reporting any bugs or issues
you encounter. The Django ticket tracker is the central place to you encounter. The Django ticket tracker is the central place to
search for open issues: search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem Please open new tickets if no existing ticket corresponds to a problem
you're running into. you're running into.
@ -152,7 +152,7 @@ Additionally, discussion of Django development, including progress
toward the 1.2 release, takes place daily on the django-developers toward the 1.2 release, takes place daily on the django-developers
mailing list: mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -161,7 +161,7 @@ discussions there.
Django's online documentation also includes pointers on how to Django's online documentation also includes pointers on how to
contribute to Django: contribute to Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation Contributions on any level -- developing code, writing documentation
or simply triaging tickets and helping to test proposed bugfixes -- or simply triaging tickets and helping to test proposed bugfixes --

View File

@ -76,7 +76,7 @@ release candidate in a safe testing environment and reporting any bugs
or issues you encounter. The Django ticket tracker is the central or issues you encounter. The Django ticket tracker is the central
place to search for open issues: place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open a new ticket only if no existing ticket corresponds to a Please open a new ticket only if no existing ticket corresponds to a
problem you're running into. problem you're running into.
@ -85,7 +85,7 @@ Additionally, discussion of Django development, including progress
toward the 1.2 release, takes place daily on the django-developers toward the 1.2 release, takes place daily on the django-developers
mailing list: mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -94,7 +94,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -28,14 +28,14 @@ token's presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis: requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using * Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest. XMLHttpRequest.
* Browsers have strict same-origin policies regarding * Browsers have strict same-origin policies regarding
XMLHttpRequest. XMLHttpRequest.
* In the context of a browser, the only way that a custom header * In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest. of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header. that appeared to be AJAX on the basis of the X-Requested-With header.

View File

@ -18,22 +18,22 @@ Overview
Django 1.2 introduces several large, important new features, including: Django 1.2 introduces several large, important new features, including:
* Support for `multiple database connections`_ in a single Django instance. * Support for `multiple database connections`_ in a single Django instance.
* `Model validation`_ inspired by Django's form validation. * `Model validation`_ inspired by Django's form validation.
* Vastly `improved protection against Cross-Site Request Forgery`_ (CSRF). * Vastly `improved protection against Cross-Site Request Forgery`_ (CSRF).
* A new `user "messages" framework`_ with support for cookie- and session-based * A new `user "messages" framework`_ with support for cookie- and session-based
message for both anonymous and authenticated users. message for both anonymous and authenticated users.
* Hooks for `object-level permissions`_, `permissions for anonymous users`_, * Hooks for `object-level permissions`_, `permissions for anonymous users`_,
and `more flexible username requirements`_. and `more flexible username requirements`_.
* Customization of email sending via `email backends`_. * Customization of email sending via `email backends`_.
* New :ref:`"smart" if template tag <new-in-1.2-smart-if>` which supports * New :ref:`"smart" if template tag <new-in-1.2-smart-if>` which supports
comparison operators. comparison operators.
.. _multiple database connections: `support for multiple databases`_ .. _multiple database connections: `support for multiple databases`_
.. _improved protection against Cross-Site Request Forgery: `improved CSRF protection`_ .. _improved protection against Cross-Site Request Forgery: `improved CSRF protection`_
@ -58,31 +58,31 @@ manner per :doc:`our API stability policy </misc/api-stability>` policy.
However, a handful of features *have* changed in ways that, for some users, will be However, a handful of features *have* changed in ways that, for some users, will be
backwards-incompatible. The big changes are: backwards-incompatible. The big changes are:
* Support for Python 2.3 has been dropped. See the full notes * Support for Python 2.3 has been dropped. See the full notes
below. below.
* The new CSRF protection framework is not backwards-compatible with * The new CSRF protection framework is not backwards-compatible with
the old system. Users of the old system will not be affected until the old system. Users of the old system will not be affected until
the old system is removed in Django 1.4. the old system is removed in Django 1.4.
However, upgrading to the new CSRF protection framework requires a few However, upgrading to the new CSRF protection framework requires a few
important backwards-incompatible changes, detailed in `CSRF Protection`_, important backwards-incompatible changes, detailed in `CSRF Protection`_,
below. below.
* Authors of custom :class:`~django.db.models.Field` subclasses should be * Authors of custom :class:`~django.db.models.Field` subclasses should be
aware that a number of methods have had a change in prototype, detailed aware that a number of methods have had a change in prototype, detailed
under `get_db_prep_*() methods on Field`_, below. under `get_db_prep_*() methods on Field`_, below.
* The internals of template tags have changed somewhat; authors of custom * The internals of template tags have changed somewhat; authors of custom
template tags that need to store state (e.g. custom control flow tags) template tags that need to store state (e.g. custom control flow tags)
should ensure that their code follows the new rules for `stateful template should ensure that their code follows the new rules for `stateful template
tags`_ tags`_
* The :func:`~django.contrib.auth.decorators.user_passes_test`, * The :func:`~django.contrib.auth.decorators.user_passes_test`,
:func:`~django.contrib.auth.decorators.login_required`, and :func:`~django.contrib.auth.decorators.login_required`, and
:func:`~django.contrib.auth.decorators.permission_required`, decorators :func:`~django.contrib.auth.decorators.permission_required`, decorators
from :mod:`django.contrib.auth` only apply to functions and no longer from :mod:`django.contrib.auth` only apply to functions and no longer
work on methods. There's a simple one-line fix `detailed below`_. work on methods. There's a simple one-line fix `detailed below`_.
.. _detailed below: `user_passes_test, login_required and permission_required`_ .. _detailed below: `user_passes_test, login_required and permission_required`_
@ -429,28 +429,28 @@ We've made large changes to the way CSRF protection works, detailed in
:doc:`the CSRF documentation </ref/contrib/csrf>`. Here are the major changes you :doc:`the CSRF documentation </ref/contrib/csrf>`. Here are the major changes you
should be aware of: should be aware of:
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and
will be removed completely in Django 1.4, in favor of a template tag that will be removed completely in Django 1.4, in favor of a template tag that
should be inserted into forms. should be inserted into forms.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This * All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the ``csrf_token`` template tag in the template. If you requires the use of the ``csrf_token`` template tag in the template. If you
have used custom templates for contrib views, you MUST READ THE UPGRADE have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates. INSTRUCTIONS to fix those templates.
.. admonition:: Documentation removed .. admonition:: Documentation removed
The upgrade notes have been removed in current Django docs. Please refer The upgrade notes have been removed in current Django docs. Please refer
to the docs for Django 1.3 or older to find these instructions. to the docs for Django 1.3 or older to find these instructions.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by * ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
default. This turns on CSRF protection by default, so views that accept default. This turns on CSRF protection by default, so views that accept
POST requests need to be written to work with the middleware. Instructions POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs. on how to do this are found in the CSRF docs.
* All of the CSRF has moved from contrib to core (with backwards * All of the CSRF has moved from contrib to core (with backwards
compatible imports in the old locations, which are deprecated and compatible imports in the old locations, which are deprecated and
will cease to be supported in Django 1.4). will cease to be supported in Django 1.4).
``get_db_prep_*()`` methods on ``Field`` ``get_db_prep_*()`` methods on ``Field``
---------------------------------------- ----------------------------------------
@ -816,20 +816,20 @@ shortened. The previous sample settings would now look like this::
This affects the following settings: This affects the following settings:
========================================= ========================== ========================================= ==========================
Old setting New Setting Old setting New Setting
========================================= ========================== ========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE` :setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST` :setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME` :setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS` :setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD` :setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT` :setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER` :setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET` :setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION` :setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME` :setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ========================== ========================================= ==========================
These changes are also required if you have manually created a database These changes are also required if you have manually created a database
connection using ``DatabaseWrapper()`` from your database backend of choice. connection using ``DatabaseWrapper()`` from your database backend of choice.
@ -967,9 +967,9 @@ Or, when directly formatting a date value::
The same applies to the globals found in ``django.forms.fields``: The same applies to the globals found in ``django.forms.fields``:
* ``DEFAULT_DATE_INPUT_FORMATS`` * ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS`` * ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_FORMATS`` * ``DEFAULT_DATETIME_INPUT_FORMATS``
Use ``django.utils.formats.get_format()`` to get the appropriate formats. Use ``django.utils.formats.get_format()`` to get the appropriate formats.

View File

@ -150,15 +150,15 @@ To compensate for this, the focus of the Django 1.3 development
process has been on adding lots of smaller, long standing feature process has been on adding lots of smaller, long standing feature
requests. These include: requests. These include:
* Improved tools for accessing and manipulating the current Site via * Improved tools for accessing and manipulating the current Site via
:func:`django.contrib.sites.models.get_current_site`. :func:`django.contrib.sites.models.get_current_site`.
* A :class:`~django.test.client.RequestFactory` for mocking * A :class:`~django.test.client.RequestFactory` for mocking
requests in tests. requests in tests.
* A new test assertion -- * A new test assertion --
:meth:`~django.test.client.Client.assertNumQueries` -- making it :meth:`~django.test.client.Client.assertNumQueries` -- making it
easier to test the database activity associated with a view. easier to test the database activity associated with a view.
.. _backwards-incompatible-changes-1.3-alpha-1: .. _backwards-incompatible-changes-1.3-alpha-1:
@ -265,9 +265,9 @@ Localflavor changes
Django 1.3 introduces the following backwards-incompatible changes to Django 1.3 introduces the following backwards-incompatible changes to
local flavors: local flavors:
* Indonesia (id) -- The province "Nanggroe Aceh Darussalam (NAD)" * Indonesia (id) -- The province "Nanggroe Aceh Darussalam (NAD)"
has been removed from the province list in favor of the new has been removed from the province list in favor of the new
official designation "Aceh (ACE)". official designation "Aceh (ACE)".
Features deprecated in 1.3 Features deprecated in 1.3
@ -312,10 +312,10 @@ As a result of the introduction of class-based generic views, the
function-based generic views provided by Django have been deprecated. function-based generic views provided by Django have been deprecated.
The following modules and the views they contain have been deprecated: The following modules and the views they contain have been deprecated:
* :mod:`django.views.generic.create_update` * :mod:`django.views.generic.create_update`
* :mod:`django.views.generic.date_based` * :mod:`django.views.generic.date_based`
* :mod:`django.views.generic.list_detail` * :mod:`django.views.generic.list_detail`
* :mod:`django.views.generic.simple` * :mod:`django.views.generic.simple`
Test client response ``template`` attribute Test client response ``template`` attribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -373,7 +373,7 @@ Django team by trying out the alpha codebase in a safe test environment and
reporting any bugs or issues you encounter. The Django ticket tracker is the reporting any bugs or issues you encounter. The Django ticket tracker is the
central place to search for open issues: central place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem you're Please open new tickets if no existing ticket corresponds to a problem you're
running into. running into.
@ -381,7 +381,7 @@ running into.
Additionally, discussion of Django development, including progress toward the Additionally, discussion of Django development, including progress toward the
1.3 release, takes place daily on the django-developers mailing list: 1.3 release, takes place daily on the django-developers mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -390,7 +390,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and
@ -399,4 +399,4 @@ appreciated.
Several development sprints will also be taking place before the 1.3 Several development sprints will also be taking place before the 1.3
release; these will typically be announced in advance on the release; these will typically be announced in advance on the
django-developers mailing list, and anyone who wants to help is django-developers mailing list, and anyone who wants to help is
welcome to join in. welcome to join in.

View File

@ -29,11 +29,11 @@ setting is ``True``) when using the :djadmin:`runserver` management command.
Based on feedback from the community this release adds two new options to the Based on feedback from the community this release adds two new options to the
:djadmin:`runserver` command to modify this behavior: :djadmin:`runserver` command to modify this behavior:
* ``--nostatic``: prevents the :djadmin:`runserver` command from serving * ``--nostatic``: prevents the :djadmin:`runserver` command from serving
files completely. files completely.
* ``--insecure``: enables serving of static files even if running with * ``--insecure``: enables serving of static files even if running with
:setting:`DEBUG` set to False. (This is **not** recommended!) :setting:`DEBUG` set to False. (This is **not** recommended!)
See the :doc:`staticfiles reference documentation </ref/contrib/staticfiles>` See the :doc:`staticfiles reference documentation </ref/contrib/staticfiles>`
for more details, or learn :doc:`how to manage static files for more details, or learn :doc:`how to manage static files
@ -100,25 +100,25 @@ desired outside the use of the optional :mod:`~django.contrib.staticfiles` app.
As a result, we took the following steps to rectify the issue: As a result, we took the following steps to rectify the issue:
* Two new global settings were added that will be used by, **but are not * Two new global settings were added that will be used by, **but are not
limited to**, the :doc:`staticfiles</ref/contrib/staticfiles>` app: limited to**, the :doc:`staticfiles</ref/contrib/staticfiles>` app:
* :setting:`STATIC_ROOT` (formally ``STATICFILES_ROOT``) * :setting:`STATIC_ROOT` (formally ``STATICFILES_ROOT``)
* :setting:`STATIC_URL` (formally ``STATICFILES_URL``) * :setting:`STATIC_URL` (formally ``STATICFILES_URL``)
* The ``django.contrib.staticfiles.templatetags.staticfiles.get_staticfiles_prefix`` * The ``django.contrib.staticfiles.templatetags.staticfiles.get_staticfiles_prefix``
template tag was moved to Django's core (``django.templatetags.static``) and template tag was moved to Django's core (``django.templatetags.static``) and
renamed to :ttag:`get_static_prefix`. renamed to :ttag:`get_static_prefix`.
* The ``django.contrib.staticfiles.context_processors.staticfiles`` * The ``django.contrib.staticfiles.context_processors.staticfiles``
context processor was moved to Django's core context processor was moved to Django's core
(``django.core.context_processors.static``) and renamed to (``django.core.context_processors.static``) and renamed to
:func:`~django.core.context_processors.static`. :func:`~django.core.context_processors.static`.
* :ref:`form-media-paths` now uses :setting:`STATIC_URL` as the prefix * :ref:`form-media-paths` now uses :setting:`STATIC_URL` as the prefix
**if the value is not None**, and falls back to the previously used **if the value is not None**, and falls back to the previously used
:setting:`MEDIA_URL` setting otherwise. :setting:`MEDIA_URL` setting otherwise.
Changes to the login methods of the admin Changes to the login methods of the admin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -209,7 +209,7 @@ Django team by trying out the beta codebase in a safe test environment and
reporting any bugs or issues you encounter. The Django ticket tracker is the reporting any bugs or issues you encounter. The Django ticket tracker is the
central place to search for open issues: central place to search for open issues:
* http://code.djangoproject.com/timeline * http://code.djangoproject.com/timeline
Please open new tickets if no existing ticket corresponds to a problem you're Please open new tickets if no existing ticket corresponds to a problem you're
running into. running into.
@ -217,7 +217,7 @@ running into.
Additionally, discussion of Django development, including progress toward the Additionally, discussion of Django development, including progress toward the
1.3 release, takes place daily on the django-developers mailing list: 1.3 release, takes place daily on the django-developers mailing list:
* http://groups.google.com/group/django-developers * http://groups.google.com/group/django-developers
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
interested in helping out with Django's development, feel free to join the interested in helping out with Django's development, feel free to join the
@ -226,7 +226,7 @@ discussions there.
Django's online documentation also includes pointers on how to contribute to Django's online documentation also includes pointers on how to contribute to
Django: Django:
* :doc:`How to contribute to Django </internals/contributing/index>` * :doc:`How to contribute to Django </internals/contributing/index>`
Contributions on any level -- developing code, writing documentation or simply Contributions on any level -- developing code, writing documentation or simply
triaging tickets and helping to test proposed bugfixes -- are always welcome and triaging tickets and helping to test proposed bugfixes -- are always welcome and

View File

@ -188,17 +188,17 @@ Improvements to built-in template tags
A number of improvements have been made to Django's built-in template tags: A number of improvements have been made to Django's built-in template tags:
* The :ttag:`include` tag now accepts a ``with`` option, allowing * The :ttag:`include` tag now accepts a ``with`` option, allowing
you to specify context variables to the included template you to specify context variables to the included template
* The :ttag:`include` tag now accepts an ``only`` option, allowing * The :ttag:`include` tag now accepts an ``only`` option, allowing
you to exclude the current context from the included context you to exclude the current context from the included context
* The :ttag:`with` tag now allows you to define multiple context * The :ttag:`with` tag now allows you to define multiple context
variables in a single :ttag:`with` block. variables in a single :ttag:`with` block.
* The :ttag:`load` tag now accepts a ``from`` argument, allowing * The :ttag:`load` tag now accepts a ``from`` argument, allowing
you to load a single tag or filter from a library. you to load a single tag or filter from a library.
TemplateResponse TemplateResponse
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -573,39 +573,39 @@ found on disk, namely:
For translatable literals found in Python code and templates (``'django'`` For translatable literals found in Python code and templates (``'django'``
gettext domain): gettext domain):
* Priorities of translations included with applications listed in the * Priorities of translations included with applications listed in the
:setting:`INSTALLED_APPS` setting were changed. To provide a behavior :setting:`INSTALLED_APPS` setting were changed. To provide a behavior
consistent with other parts of Django that also use such setting (templates, consistent with other parts of Django that also use such setting (templates,
etc.) now, when building the translation that will be made available, the etc.) now, when building the translation that will be made available, the
apps listed first have higher precedence than the ones listed later. apps listed first have higher precedence than the ones listed later.
* Now it is possible to override the translations shipped with applications by * Now it is possible to override the translations shipped with applications by
using the :setting:`LOCALE_PATHS` setting whose translations have now higher using the :setting:`LOCALE_PATHS` setting whose translations have now higher
precedence than the translations of :setting:`INSTALLED_APPS` applications. precedence than the translations of :setting:`INSTALLED_APPS` applications.
The relative priority among the values listed in this setting has also been The relative priority among the values listed in this setting has also been
modified so the paths listed first have higher precedence than the modified so the paths listed first have higher precedence than the
ones listed later. ones listed later.
* The ``locale`` subdirectory of the directory containing the settings, that * The ``locale`` subdirectory of the directory containing the settings, that
usually coincides with and is know as the *project directory* is being usually coincides with and is know as the *project directory* is being
deprecated in this release as a source of translations. (the precedence of deprecated in this release as a source of translations. (the precedence of
these translations is intermediate between applications and :setting:`LOCALE_PATHS` these translations is intermediate between applications and :setting:`LOCALE_PATHS`
translations). See the `corresponding deprecated features section`_ translations). See the `corresponding deprecated features section`_
of this document. of this document.
For translatable literals found in Javascript code (``'djangojs'`` gettext For translatable literals found in Javascript code (``'djangojs'`` gettext
domain): domain):
* Similarly to the ``'django'`` domain translations: Overriding of * Similarly to the ``'django'`` domain translations: Overriding of
translations shipped with applications by using the :setting:`LOCALE_PATHS` translations shipped with applications by using the :setting:`LOCALE_PATHS`
setting is now possible for this domain too. These translations have higher setting is now possible for this domain too. These translations have higher
precedence than the translations of Python packages passed to the precedence than the translations of Python packages passed to the
:ref:`javascript_catalog view <javascript_catalog-view>`. Paths listed first :ref:`javascript_catalog view <javascript_catalog-view>`. Paths listed first
have higher precedence than the ones listed later. have higher precedence than the ones listed later.
* Translations under the ``locale`` subdirectory of the *project directory* * Translations under the ``locale`` subdirectory of the *project directory*
have never been taken in account for JavaScript translations and remain in have never been taken in account for JavaScript translations and remain in
the same situation considering the deprecation of such location. the same situation considering the deprecation of such location.
.. _corresponding deprecated features section: loading_of_project_level_translations_ .. _corresponding deprecated features section: loading_of_project_level_translations_

View File

@ -94,15 +94,15 @@ two most common are `python-memcached`_ and `pylibmc`_.
To use Memcached with Django: To use Memcached with Django:
* Set :setting:`BACKEND <CACHES-BACKEND>` to * Set :setting:`BACKEND <CACHES-BACKEND>` to
``django.core.cache.backends.memcached.MemcachedCache`` or ``django.core.cache.backends.memcached.MemcachedCache`` or
``django.core.cache.backends.memcached.PyLibMCCache`` (depending ``django.core.cache.backends.memcached.PyLibMCCache`` (depending
on your chosen memcached binding) on your chosen memcached binding)
* Set :setting:`LOCATION <CACHES-LOCATION>` to ``ip:port`` values, * Set :setting:`LOCATION <CACHES-LOCATION>` to ``ip:port`` values,
where ``ip`` is the IP address of the Memcached daemon and ``port`` is the where ``ip`` is the IP address of the Memcached daemon and ``port`` is the
port on which Memcached is running, or to a ``unix:path`` value, where port on which Memcached is running, or to a ``unix:path`` value, where
``path`` is the path to a Memcached Unix socket file. ``path`` is the path to a Memcached Unix socket file.
In this example, Memcached is running on localhost (127.0.0.1) port 11211, using In this example, Memcached is running on localhost (127.0.0.1) port 11211, using
the ``python-memcached`` binding:: the ``python-memcached`` binding::
@ -358,55 +358,55 @@ backend, each cache backend can be given additional arguments to
control caching behavior. These arguments are provided as additional control caching behavior. These arguments are provided as additional
keys in the :setting:`CACHES` setting. Valid arguments are as follows: keys in the :setting:`CACHES` setting. Valid arguments are as follows:
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in * :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
seconds, to use for the cache. This argument defaults to 300 seconds, to use for the cache. This argument defaults to 300
seconds (5 minutes). seconds (5 minutes).
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be * :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
passed to cache backend. The list options understood by each passed to cache backend. The list options understood by each
backend vary with each backend. backend vary with each backend.
Cache backends that implement their own culling strategy (i.e., Cache backends that implement their own culling strategy (i.e.,
the ``locmem``, ``filesystem`` and ``database`` backends) will the ``locmem``, ``filesystem`` and ``database`` backends) will
honor the following options: honor the following options:
* ``MAX_ENTRIES``: the maximum number of entries allowed in * ``MAX_ENTRIES``: the maximum number of entries allowed in
the cache before old values are deleted. This argument the cache before old values are deleted. This argument
defaults to ``300``. defaults to ``300``.
* ``CULL_FREQUENCY``: The fraction of entries that are culled * ``CULL_FREQUENCY``: The fraction of entries that are culled
when ``MAX_ENTRIES`` is reached. The actual ratio is when ``MAX_ENTRIES`` is reached. The actual ratio is
``1/CULL_FREQUENCY``, so set ``CULL_FREQUENCY``: to ``2`` to ``1/CULL_FREQUENCY``, so set ``CULL_FREQUENCY``: to ``2`` to
cull half of the entries when ``MAX_ENTRIES`` is reached. cull half of the entries when ``MAX_ENTRIES`` is reached.
A value of ``0`` for ``CULL_FREQUENCY`` means that the A value of ``0`` for ``CULL_FREQUENCY`` means that the
entire cache will be dumped when ``MAX_ENTRIES`` is reached. entire cache will be dumped when ``MAX_ENTRIES`` is reached.
This makes culling *much* faster at the expense of more This makes culling *much* faster at the expense of more
cache misses. cache misses.
Cache backends backed by a third-party library will pass their Cache backends backed by a third-party library will pass their
options directly to the underlying cache library. As a result, options directly to the underlying cache library. As a result,
the list of valid options depends on the library in use. the list of valid options depends on the library in use.
* :setting:`KEY_PREFIX <CACHES-KEY_PREFIX>`: A string that will be * :setting:`KEY_PREFIX <CACHES-KEY_PREFIX>`: A string that will be
automatically included (prepended by default) to all cache keys automatically included (prepended by default) to all cache keys
used by the Django server. used by the Django server.
See the :ref:`cache documentation <cache_key_prefixing>` for See the :ref:`cache documentation <cache_key_prefixing>` for
more information. more information.
* :setting:`VERSION <CACHES-VERSION>`: The default version number * :setting:`VERSION <CACHES-VERSION>`: The default version number
for cache keys generated by the Django server. for cache keys generated by the Django server.
See the :ref:`cache documentation <cache_versioning>` for more See the :ref:`cache documentation <cache_versioning>` for more
information. information.
* :setting:`KEY_FUNCTION <CACHES-KEY_FUNCTION>` * :setting:`KEY_FUNCTION <CACHES-KEY_FUNCTION>`
A string containing a dotted path to a function that defines how A string containing a dotted path to a function that defines how
to compose a prefix, version and key into a final cache key. to compose a prefix, version and key into a final cache key.
See the :ref:`cache documentation <cache_key_transformation>` See the :ref:`cache documentation <cache_key_transformation>`
for more information. for more information.
In this example, a filesystem backend is being configured with a timeout In this example, a filesystem backend is being configured with a timeout
of 60 seconds, and a maximum capacity of 1000 items:: of 60 seconds, and a maximum capacity of 1000 items::
@ -470,14 +470,14 @@ response for HEAD request.
Additionally, the cache middleware automatically sets a few headers in each Additionally, the cache middleware automatically sets a few headers in each
:class:`~django.http.HttpResponse`: :class:`~django.http.HttpResponse`:
* Sets the ``Last-Modified`` header to the current date/time when a fresh * Sets the ``Last-Modified`` header to the current date/time when a fresh
(uncached) version of the page is requested. (uncached) version of the page is requested.
* Sets the ``Expires`` header to the current date/time plus the defined * Sets the ``Expires`` header to the current date/time plus the defined
:setting:`CACHE_MIDDLEWARE_SECONDS`. :setting:`CACHE_MIDDLEWARE_SECONDS`.
* Sets the ``Cache-Control`` header to give a max age for the page -- * Sets the ``Cache-Control`` header to give a max age for the page --
again, from the :setting:`CACHE_MIDDLEWARE_SECONDS` setting. again, from the :setting:`CACHE_MIDDLEWARE_SECONDS` setting.
See :doc:`/topics/http/middleware` for more on middleware. See :doc:`/topics/http/middleware` for more on middleware.
@ -932,21 +932,21 @@ reaches your Web site.
Here are a few examples of upstream caches: Here are a few examples of upstream caches:
* Your ISP may cache certain pages, so if you requested a page from * Your ISP may cache certain pages, so if you requested a page from
http://example.com/, your ISP would send you the page without having to http://example.com/, your ISP would send you the page without having to
access example.com directly. The maintainers of example.com have no access example.com directly. The maintainers of example.com have no
knowledge of this caching; the ISP sits between example.com and your Web knowledge of this caching; the ISP sits between example.com and your Web
browser, handling all of the caching transparently. browser, handling all of the caching transparently.
* Your Django Web site may sit behind a *proxy cache*, such as Squid Web * Your Django Web site may sit behind a *proxy cache*, such as Squid Web
Proxy Cache (http://www.squid-cache.org/), that caches pages for Proxy Cache (http://www.squid-cache.org/), that caches pages for
performance. In this case, each request first would be handled by the performance. In this case, each request first would be handled by the
proxy, and it would be passed to your application only if needed. proxy, and it would be passed to your application only if needed.
* Your Web browser caches pages, too. If a Web page sends out the * Your Web browser caches pages, too. If a Web page sends out the
appropriate headers, your browser will use the local cached copy for appropriate headers, your browser will use the local cached copy for
subsequent requests to that page, without even contacting the Web page subsequent requests to that page, without even contacting the Web page
again to see whether it has changed. again to see whether it has changed.
Upstream caching is a nice efficiency boost, but there's a danger to it: Upstream caching is a nice efficiency boost, but there's a danger to it:
Many Web pages' contents differ based on authentication and a host of other Many Web pages' contents differ based on authentication and a host of other
@ -1099,12 +1099,12 @@ entries may be cached on any shared cache. The following code uses
There are a few other ways to control cache parameters. For example, HTTP There are a few other ways to control cache parameters. For example, HTTP
allows applications to do the following: allows applications to do the following:
* Define the maximum time a page should be cached. * Define the maximum time a page should be cached.
* Specify whether a cache should always check for newer versions, only * Specify whether a cache should always check for newer versions, only
delivering the cached content when there are no changes. (Some caches delivering the cached content when there are no changes. (Some caches
might deliver cached content even if the server page changed, simply might deliver cached content even if the server page changed, simply
because the cache copy isn't yet expired.) because the cache copy isn't yet expired.)
In Django, use the ``cache_control`` view decorator to specify these cache In Django, use the ``cache_control`` view decorator to specify these cache
parameters. In this example, ``cache_control`` tells caches to revalidate the parameters. In this example, ``cache_control`` tells caches to revalidate the
@ -1119,14 +1119,14 @@ cache on every access and to store cached versions for, at most, 3,600 seconds::
Any valid ``Cache-Control`` HTTP directive is valid in ``cache_control()``. Any valid ``Cache-Control`` HTTP directive is valid in ``cache_control()``.
Here's a full list: Here's a full list:
* ``public=True`` * ``public=True``
* ``private=True`` * ``private=True``
* ``no_cache=True`` * ``no_cache=True``
* ``no_transform=True`` * ``no_transform=True``
* ``must_revalidate=True`` * ``must_revalidate=True``
* ``proxy_revalidate=True`` * ``proxy_revalidate=True``
* ``max_age=num_seconds`` * ``max_age=num_seconds``
* ``s_maxage=num_seconds`` * ``s_maxage=num_seconds``
For explanation of Cache-Control HTTP directives, see the `Cache-Control spec`_. For explanation of Cache-Control HTTP directives, see the `Cache-Control spec`_.
@ -1154,12 +1154,12 @@ Other optimizations
Django comes with a few other pieces of middleware that can help optimize your Django comes with a few other pieces of middleware that can help optimize your
site's performance: site's performance:
* ``django.middleware.http.ConditionalGetMiddleware`` adds support for * ``django.middleware.http.ConditionalGetMiddleware`` adds support for
modern browsers to conditionally GET responses based on the ``ETag`` modern browsers to conditionally GET responses based on the ``ETag``
and ``Last-Modified`` headers. and ``Last-Modified`` headers.
* :class:`django.middleware.gzip.GZipMiddleware` compresses responses for all * :class:`django.middleware.gzip.GZipMiddleware` compresses responses for all
modern browsers, saving bandwidth and transfer time. modern browsers, saving bandwidth and transfer time.
Order of MIDDLEWARE_CLASSES Order of MIDDLEWARE_CLASSES
=========================== ===========================
@ -1175,9 +1175,9 @@ response phase. Thus, you need to make sure that ``UpdateCacheMiddleware``
appears *before* any other middleware that might add something to the ``Vary`` appears *before* any other middleware that might add something to the ``Vary``
header. The following middleware modules do so: header. The following middleware modules do so:
* ``SessionMiddleware`` adds ``Cookie`` * ``SessionMiddleware`` adds ``Cookie``
* ``GZipMiddleware`` adds ``Accept-Encoding`` * ``GZipMiddleware`` adds ``Accept-Encoding``
* ``LocaleMiddleware`` adds ``Accept-Language`` * ``LocaleMiddleware`` adds ``Accept-Language``
``FetchFromCacheMiddleware``, on the other hand, runs during the request phase, ``FetchFromCacheMiddleware``, on the other hand, runs during the request phase,
where middleware is applied first-to-last, so an item at the top of the list where middleware is applied first-to-last, so an item at the top of the list

Some files were not shown because too many files have changed in this diff Show More