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
things:
* Set the :setting:`SESSION_COOKIE_DOMAIN` setting in your admin config
file to match your domain. For example, if you're going to
"http://www.example.com/admin/" in your browser, in
"myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``.
* Set the :setting:`SESSION_COOKIE_DOMAIN` setting in your admin config
file to match your domain. For example, if you're going to
"http://www.example.com/admin/" in your browser, in
"myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``.
* 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"
or another domain that doesn't have a dot in it, try going to
"localhost.localdomain" or "127.0.0.1". And set
:setting:`SESSION_COOKIE_DOMAIN` accordingly.
* 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"
or another domain that doesn't have a dot in it, try going to
"localhost.localdomain" or "127.0.0.1". And set
: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.
-----------------------------------------------------------------------------------------------------------------------------------------------------------

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
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
touches a dependency (such as PIL), a contrib module, or a specific
database, are those instructions clear enough even for someone not
familiar with it?
* Are there clear instructions on how to reproduce the bug? If this
touches a dependency (such as PIL), a contrib module, or a specific
database, are those instructions clear enough even for someone not
familiar with it?
* If there are several patches attached to the ticket, is it clear what
each one does, which ones can be ignored and which matter?
* If there are several patches attached to the ticket, is it clear what
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
explanation why not? A test expresses succinctly what the problem is,
and shows that the patch actually fixes it.
* 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,
and shows that the patch actually fixes 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

View File

@ -4,11 +4,11 @@ FAQ: Installation
How do I get started?
---------------------
#. `Download the code`_.
#. Install Django (read the :doc:`installation guide </intro/install>`).
#. Walk through the :doc:`tutorial </intro/tutorial01>`.
#. Check out the rest of the :doc:`documentation </index>`, and `ask questions`_ if you
run into trouble.
#. `Download the code`_.
#. Install Django (read the :doc:`installation guide </intro/install>`).
#. Walk through the :doc:`tutorial </intro/tutorial01>`.
#. Check out the rest of the :doc:`documentation </index>`, and `ask questions`_ if you
run into trouble.
.. _`Download the code`: http://www.djangoproject.com/download/
.. _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:
* The environment variable DJANGO_SETTINGS_MODULE is set to a
fully-qualified Python module (i.e. "mysite.settings").
* The environment variable DJANGO_SETTINGS_MODULE is set to a
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,
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
the following::
* 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
``SetEnv``; before you import anything from Django you'll need to do
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?
----------------------------------------------------------
@ -46,25 +46,25 @@ How do I use image and file fields?
Using a :class:`~django.db.models.FileField` or an
: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
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.)
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
account.
#. 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. (For performance, these files are not stored in the database.)
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
account.
#. Add the :class:`~django.db.models.FileField` or
:class:`~django.db.models.ImageField` to your model, making sure to
define the :attr:`~django.db.models.FileField.upload_to` option to tell
Django to which subdirectory of :setting:`MEDIA_ROOT` it should upload
files.
#. Add the :class:`~django.db.models.FileField` or
:class:`~django.db.models.ImageField` to your model, making sure to
define the :attr:`~django.db.models.FileField.upload_to` option to tell
Django to which subdirectory of :setting:`MEDIA_ROOT` it should upload
files.
#. 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
convenience :attr:`~django.core.files.File.url` attribute provided by
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
template with ``{{ object.mug_shot.url }}``.
#. 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
convenience :attr:`~django.core.files.File.url` attribute provided by
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
template with ``{{ object.mug_shot.url }}``.
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
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
a certain permission.
* Authenticate access to a Subversion_ repository against Django users with
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/
.. _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
``PythonOption`` directives to modify this behavior:
================================ =========================================
``PythonOption`` Explanation
================================ =========================================
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
those with the ``is_staff`` flag set)
will be allowed.
================================ =========================================
``PythonOption`` Explanation
================================ =========================================
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
those with the ``is_staff`` flag set)
will be allowed.
Defaults to ``on``.
Defaults to ``on``.
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
those with the ``is_superuser`` flag set)
will be allowed.
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
those with the ``is_superuser`` flag set)
will be allowed.
Defaults to ``off``.
Defaults to ``off``.
``DjangoPermissionName`` The name of a permission to require for
access. See :ref:`custom permissions
<custom-permissions>` for more
information.
``DjangoPermissionName`` The name of a permission to require for
access. See :ref:`custom permissions
<custom-permissions>` for more
information.
By default no specific permission will be
required.
================================ =========================================
By default no specific permission will be
required.
================================ =========================================
Note that sometimes ``SetEnv`` doesn't play well in this mod_python
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
:doc:`/ref/files/storage`, but you **must** implement the following methods:
* :meth:`Storage.delete`
* :meth:`Storage.exists`
* :meth:`Storage.listdir`
* :meth:`Storage.size`
* :meth:`Storage.url`
* :meth:`Storage.delete`
* :meth:`Storage.exists`
* :meth:`Storage.listdir`
* :meth:`Storage.size`
* :meth:`Storage.url`
You'll also usually want to use hooks specifically designed for custom storage
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
classes when you want a custom field:
* 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
displaying purposes, things like that. This is the ``Hand`` class in our
example.
* 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
displaying purposes, things like that. This is the ``Hand`` class in our
example.
* 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
storage form and the Python form.
* 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
storage form and the Python form.
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
parameters:
* :attr:`~django.db.models.Field.verbose_name`
* :attr:`~django.db.models.Field.name`
* :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.Field.max_length`
* :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index`
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
:class:`ForeignKey`). For advanced use only.
* :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable`
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
not be serialized when the model is passed to Django's :doc:`serializers
</topics/serialization>`. Defaults to ``True``.
* :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
the Oracle backend and only for index creation. You can usually ignore
this option.
* :attr:`~django.db.models.Field.auto_created`: True if the field was
automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only.
* :attr:`~django.db.models.Field.verbose_name`
* :attr:`~django.db.models.Field.name`
* :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.Field.max_length`
* :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index`
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
:class:`ForeignKey`). For advanced use only.
* :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable`
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
not be serialized when the model is passed to Django's :doc:`serializers
</topics/serialization>`. Defaults to ``True``.
* :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
the Oracle backend and only for index creation. You can usually ignore
this option.
* :attr:`~django.db.models.Field.auto_created`: True if the field was
automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only.
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
@ -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
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
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
smoothly:
1. Look at the existing Django fields (in
: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,
instead of creating an entirely new field from scratch.
1. Look at the existing Django fields (in
: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,
instead of creating an entirely new field from scratch.
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
behavior of the field code is to call
:func:`~django.utils.encoding.force_unicode` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your :meth:`__unicode__` method automatically
converts to the string form of your Python object, you can save yourself
a lot of work.
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
behavior of the field code is to call
:func:`~django.utils.encoding.force_unicode` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your :meth:`__unicode__` method automatically
converts to the string form of your Python object, you can save yourself
a lot of work.
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
improve the efficiency and readability of the field's code.
1. The source for Django's own ``ImageField`` (in
``django/db/models/fields/files.py``) is a great example of how to
subclass ``FileField`` to support a particular type of file, as it
incorporates all of the techniques described above.
1. The source for Django's own ``ImageField`` (in
``django/db/models/fields/files.py``) is a great example of how to
subclass ``FileField`` to support a particular type of file, as it
incorporates all of the techniques described above.
2. Cache file attributes wherever possible. Since files may be stored in
remote storage systems, retrieving them may cost extra time, or even
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
reduce the number of times the file must be retrieved on subsequent
calls for that information.
2. Cache file attributes wherever possible. Since files may be stored in
remote storage systems, retrieving them may cost extra time, or even
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
reduce the number of times the file must be retrieved on subsequent
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:
* The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left
out altogether.
* The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left
out altogether.
For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
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:
1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the
function as a string).
1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the
function as a string).
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
passed around inside the template code:
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
output, they're escaped if auto-escaping is in effect and presented
unchanged, otherwise.
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
output, they're escaped if auto-escaping is in effect and presented
unchanged, otherwise.
* **Safe strings** are strings that have been marked safe from further
escaping at output time. Any necessary escaping has already been done.
They're commonly used for output that contains raw HTML that is intended
to be interpreted as-is on the client side.
* **Safe strings** are strings that have been marked safe from further
escaping at output time. Any necessary escaping has already been done.
They're commonly used for output that contains raw HTML that is intended
to be interpreted as-is on the client side.
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
They share a common base class of ``SafeData``, so you can test
for them using code like:
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
They share a common base class of ``SafeData``, so you can test
for them using code like:
.. code-block:: python
.. code-block:: python
if isinstance(value, SafeData):
# Do something with the "safe" string.
...
if isinstance(value, SafeData):
# Do something with the "safe" string.
...
* **Strings marked as "needing escaping"** are *always* escaped on
output, regardless of whether they are in an :ttag:`autoescape` block or
not. These strings are only escaped once, however, even if auto-escaping
applies.
* **Strings marked as "needing escaping"** are *always* escaped on
output, regardless of whether they are in an :ttag:`autoescape` block or
not. These strings are only escaped once, however, even if auto-escaping
applies.
Internally, these strings are of type ``EscapeString`` or
``EscapeUnicode``. Generally you don't have to worry about these; they
exist for the implementation of the :tfilter:`escape` filter.
Internally, these strings are of type ``EscapeString`` or
``EscapeUnicode``. Generally you don't have to worry about these; they
exist for the implementation of the :tfilter:`escape` filter.
Template filter code falls into one of two situations:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In
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
your filter function and set it to ``True``, like so:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In
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
your filter function and set it to ``True``, like so:
.. code-block:: python
.. code-block:: python
@register.filter
def myfilter(value):
return value
myfilter.is_safe = True
@register.filter
def myfilter(value):
return value
myfilter.is_safe = True
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
passed in, Django will automatically escape it, if necessary.
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
passed in, Django will automatically escape it, if necessary.
You can think of this as meaning "this filter is safe -- it doesn't
introduce any possibility of unsafe HTML."
You can think of this as meaning "this filter is safe -- it doesn't
introduce any possibility of unsafe HTML."
The reason ``is_safe`` is necessary is because there are plenty of
normal string operations that will turn a ``SafeData`` object back into
a normal ``str`` or ``unicode`` object and, rather than try to catch
them all, which would be very difficult, Django repairs the damage after
the filter has completed.
The reason ``is_safe`` is necessary is because there are plenty of
normal string operations that will turn a ``SafeData`` object back into
a normal ``str`` or ``unicode`` object and, rather than try to catch
them all, which would be very difficult, Django repairs the damage after
the filter has completed.
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
to the result (aside from any that were already present), you should
mark your filter with ``is_safe``:
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
to the result (aside from any that were already present), you should
mark your filter with ``is_safe``:
.. code-block:: python
.. code-block:: python
@register.filter
def add_xx(value):
return '%sxx' % value
add_xx.is_safe = True
@register.filter
def add_xx(value):
return '%sxx' % value
add_xx.is_safe = True
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
as "safe".
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
as "safe".
By default, ``is_safe`` defaults to ``False``, and you can omit it from
any filters where it isn't required.
By default, ``is_safe`` defaults to ``False``, and you can omit it from
any filters where it isn't required.
Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave
unbalanced HTML tags or entities in the result. For example, removing a
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
be escaped on output to avoid causing problems. Similarly, removing 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
this tricky, but keep an eye out for any problems like that when
reviewing your code.
Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave
unbalanced HTML tags or entities in the result. For example, removing a
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
be escaped on output to avoid causing problems. Similarly, removing 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
this tricky, but keep an eye out for any problems like that when
reviewing your code.
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
value, marking it ``is_safe`` will probably have unintended
consequences (such as converting a boolean False to the string
'False').
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
value, marking it ``is_safe`` will probably have unintended
consequences (such as converting a boolean False to the string
'False').
2. Alternatively, your filter code can manually take care of any necessary
escaping. This is necessary when you're introducing new HTML markup into
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
to handle the input yourself.
2. Alternatively, your filter code can manually take care of any necessary
escaping. This is necessary when you're introducing new HTML markup into
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
to handle the input yourself.
To mark the output as a safe string, use
:func:`django.utils.safestring.mark_safe`.
To mark the output as a safe string, use
:func:`django.utils.safestring.mark_safe`.
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
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
order to make things easier for your template authors.
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
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
order to make things easier for your template authors.
In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise.
In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise.
For example, let's write a filter that emphasizes the first character of
a string:
For example, let's write a filter that emphasizes the first character of
a string:
.. code-block:: python
.. code-block:: python
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:]
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result)
initial_letter_filter.needs_autoescape = True
def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:]
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result)
initial_letter_filter.needs_autoescape = True
The ``needs_autoescape`` attribute on the filter function and the
``autoescape`` keyword argument mean that our function will know whether
automatic escaping is in effect when the filter is called. We use
``autoescape`` to decide whether the input data needs to be passed
through ``django.utils.html.conditional_escape`` or not. (In the latter
case, we just use the identity function as the "escape" function.) The
``conditional_escape()`` function is like ``escape()`` except it only
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
instance is passed to ``conditional_escape()``, the data is returned
unchanged.
The ``needs_autoescape`` attribute on the filter function and the
``autoescape`` keyword argument mean that our function will know whether
automatic escaping is in effect when the filter is called. We use
``autoescape`` to decide whether the input data needs to be passed
through ``django.utils.html.conditional_escape`` or not. (In the latter
case, we just use the identity function as the "escape" function.) The
``conditional_escape()`` function is like ``escape()`` except it only
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
instance is passed to ``conditional_escape()``, the data is returned
unchanged.
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
escaping.
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
escaping.
There's no need to worry about the ``is_safe`` attribute in this case
(although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the
``is_safe`` attribute won't change anything either way.
There's no need to worry about the ``is_safe`` attribute in this case
(although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the
``is_safe`` attribute won't change anything either way.
Writing custom template tags
----------------------------
@ -381,37 +381,37 @@ object:
Notes:
* ``parser`` is the template parser object. We don't need it in this
example.
* ``parser`` is the template parser object. We don't need it in this
example.
* ``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"'``.
* ``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"'``.
* The ``token.split_contents()`` method separates the arguments on spaces
while keeping quoted strings together. The more straightforward
``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
idea to always use ``token.split_contents()``.
* The ``token.split_contents()`` method separates the arguments on spaces
while keeping quoted strings together. The more straightforward
``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
idea to always use ``token.split_contents()``.
* This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for
any syntax error.
* This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for
any syntax error.
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
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]``
will ''always'' be the name of your tag -- even when the tag has no
arguments.
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
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]``
will ''always'' be the name of your tag -- even when the tag has no
arguments.
* The function returns a ``CurrentTimeNode`` with everything the node needs
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
template tag are removed in ``format_string[1:-1]``.
* The function returns a ``CurrentTimeNode`` with everything the node needs
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
template tag are removed in ``format_string[1:-1]``.
* The parsing is very low-level. The Django developers have experimented
with writing small frameworks on top of this parsing system, using
techniques such as EBNF grammars, but those experiments made the template
engine too slow. It's low-level because that's fastest.
* The parsing is very low-level. The Django developers have experimented
with writing small frameworks on top of this parsing system, using
techniques such as EBNF grammars, but those experiments made the template
engine too slow. It's low-level because that's fastest.
Writing the renderer
~~~~~~~~~~~~~~~~~~~~
@ -433,14 +433,14 @@ Continuing the above example, we need to define ``CurrentTimeNode``:
Notes:
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
Always pass any options/parameters/arguments to a ``Node`` via its
``__init__()``.
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
Always pass any options/parameters/arguments to a ``Node`` via its
``__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
exception. It should fail silently, just as template filters should.
* ``render()`` should never raise ``TemplateSyntaxError`` or any other
exception. It should fail silently, just as template filters should.
Ultimately, this decoupling of compilation and rendering results in an
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
the same time:
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
returns 'row2'
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
returns 'row2'
The CycleNode is iterating, but it's iterating globally. As far as Thread 1
and Thread 2 are concerned, it's always returning the same value. This is
@ -584,10 +584,10 @@ in "Writing custom template filters" above. Example:
The ``tag()`` method takes two arguments:
1. The name of the template tag -- a string. If this is left out, the
name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the
function as a string).
1. The name of the template tag -- a string. If this is left out, the
name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the
function as a string).
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:
1. The tag name ``format_time``.
2. The string ``"blog_entry.date_updated"`` (without the surrounding
quotes).
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
``split_contents()`` will include the leading and trailing quotes for
string literals like this.
1. The tag name ``format_time``.
2. The string ``"blog_entry.date_updated"`` (without the surrounding
quotes).
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
``split_contents()`` will include the leading and trailing quotes for
string literals 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:
* 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.
* The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string.
* If the argument was a template variable, our function is passed the
current value of the variable, not the variable itself.
* 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.
* The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string.
* If the argument was a template variable, our function is passed the
current value of the variable, not the variable itself.
.. 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
things:
* Use the ``FastCGIExternalServer`` directive to specify the location of
your FastCGI server.
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
* Use the ``FastCGIExternalServer`` directive to specify the location of
your FastCGI server.
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
.. _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
Django -- for serving media. Here are some good choices:
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
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
@ -299,11 +299,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your
document root.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
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
of which has to do with Django itself.
1. It may be because your Python code is importing the "pyexpat" module,
which may conflict with the version embedded in Apache. For full
information, see `Expat Causing Apache Crash`_.
1. It may be because your Python code is importing the "pyexpat" module,
which may conflict with the version embedded in Apache. For full
information, see `Expat Causing Apache Crash`_.
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,
this causes a known mod_python issue due to version conflicts in PHP and
the Python MySQL backend. There's full information in the
`mod_python FAQ entry`_.
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,
this causes a known mod_python issue due to version conflicts in PHP and
the Python MySQL backend. There's full information in the
`mod_python FAQ entry`_.
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

View File

@ -64,11 +64,11 @@ server you choose.
We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices:
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
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
@ -131,11 +131,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your
document root.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
Details
=======

View File

@ -56,12 +56,12 @@ setting.
Django can also be configured to email errors about broken links (404 "page
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``
(which it does by default).
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
(which it does by default).
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
@ -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
local variables susceptible to contain sensitive information, you may
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):
pw = user.pass_word
cc = user.credit_card_number
name = user.name
...
@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
pw = user.pass_word
cc = user.credit_card_number
name = user.name
...
In the above example, the values for the ``user``, ``pw`` and ``cc``
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.
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)
@ -177,19 +173,17 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
:attr:`POST parameters<HttpRequest.POST>` susceptible to contain sensitive
information, you may prevent the values of those parameters from being
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):
UserProfile.create(user=request.user,
password=request.POST['pass_word'],
credit_card=request.POST['credit_card_number'],
name=request.POST['name'])
...
@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
UserProfile.create(user=request.user,
password=request.POST['pass_word'],
credit_card=request.POST['credit_card_number'],
name=request.POST['name'])
...
In the above example, the values for the ``pass_word`` and
``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.
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::
@ -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
customize this default behavior for your entire site, you need to define your
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
given view by setting the ``HttpRequest``'s ``exception_reporter_filter``
attribute:
attribute::
.. code-block:: python
def my_view(request):
if request.user.is_authenticated():
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
def my_view(request):
if request.user.is_authenticated():
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
Your custom filter class needs to inherit from
: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
translations for the same literal:
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
precedence, with the ones appearing first having higher precedence than
the ones appearing later.
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
appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or
more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale``
is used as a fallback.
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
precedence, with the ones appearing first having higher precedence than
the ones appearing later.
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
appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or
more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale``
is used as a fallback.
.. deprecated:: 1.3
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 paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above.
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above.
* ``$APPPATH/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>`
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
running on standard Python. However, are a few differences to keep in mind:
* Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it
occurs.
* Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it
occurs.
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
instead of ``PYTHONPATH``.
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
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'``
connection:
* :setting:`NAME`
* :setting:`ENGINE`
* :setting:`USER`
* :setting:`PASSWORD`
* :setting:`HOST`
* :setting:`PORT`
* :setting:`NAME`
* :setting:`ENGINE`
* :setting:`USER`
* :setting:`PASSWORD`
* :setting:`HOST`
* :setting:`PORT`
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
mention:
* 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
you leave this off, browsers will probably interpret the output as HTML,
which will result in ugly, scary gobbledygook in the browser window.
* 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
you leave this off, browsers will probably interpret the output as HTML,
which will result in ugly, scary gobbledygook in the browser window.
* The response gets an additional ``Content-Disposition`` header, which
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..."
dialogue, etc.
* The response gets an additional ``Content-Disposition`` header, which
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..."
dialogue, etc.
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
first argument to ``csv.writer``. The ``csv.writer`` function expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
first argument to ``csv.writer``. The ``csv.writer`` function expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* For each row in your CSV file, call ``writer.writerow``, passing it an
iterable object such as a list or tuple.
* For each row in your CSV file, call ``writer.writerow``, passing it an
iterable object such as a list or tuple.
* 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
``writerow()`` your raw strings, and it'll do the right thing.
* 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
``writerow()`` your raw strings, and it'll do the right thing.
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
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
section`_.
* Use the ``UnicodeWriter`` class provided in the `csv module's examples
section`_.
* Use the `python-unicodecsv module`_, which aims to be a drop-in
replacement for :mod:`csv` that gracefully handles Unicode.
* Use the `python-unicodecsv module`_, which aims to be a drop-in
replacement for :mod:`csv` that gracefully handles Unicode.
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
mention:
* 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.
If you leave this off, browsers will probably interpret the output as
HTML, which would result in ugly, scary gobbledygook in the browser
window.
* 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.
If you leave this off, browsers will probably interpret the output as
HTML, which would result in ugly, scary gobbledygook in the browser
window.
* The response gets an additional ``Content-Disposition`` header, which
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..."
dialogue, etc.
* The response gets an additional ``Content-Disposition`` header, which
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..."
dialogue, etc.
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
example. This forces Web browsers to pop-up a dialog box
prompting/confirming how to handle the document even if a default is set
on the machine. If you leave off ``'attachment;'``, browsers will handle
the PDF using whatever program/plugin they've been configured to use for
PDFs. Here's what that code would look like::
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
example. This forces Web browsers to pop-up a dialog box
prompting/confirming how to handle the document even if a default is set
on the machine. If you leave off ``'attachment;'``, browsers will handle
the PDF using whatever program/plugin they've been configured to use for
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
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``.
* Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file.
Complex PDFs
============
@ -137,13 +137,13 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`::
Further resources
=================
* PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python.
* PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python.
.. _PDFlib: http://www.pdflib.org/
.. _`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
serving your site, the basic outline gets modified to look something like:
* Push your code up to the deployment server.
* On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
* Push your code up to the deployment server.
* On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
: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
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
type of web server -- faster but less full-featured. Some good choices are:
* lighttpd_
* Nginx_
* TUX_
* Cherokee_
* A stripped-down version of Apache_
* lighttpd_
* Nginx_
* TUX_
* Cherokee_
* A stripped-down version of Apache_
.. _lighttpd: http://www.lighttpd.net/
.. _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
the deployment strategy to look something like:
* When your static files change, run :djadmin:`collectstatic` locally.
* Push your local :setting:`STATIC_ROOT` up to the static file server
into the directory that's being served. ``rsync`` is a good
choice for this step since it only needs to transfer the
bits of static files that have changed.
* When your static files change, run :djadmin:`collectstatic` locally.
* Push your local :setting:`STATIC_ROOT` up to the static file server
into the directory that's being served. ``rsync`` is a good
choice for this step since it only needs to transfer the
bits of static files that have changed.
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
``django.contrib.staticfiles``, you'll need to make a few changes:
* Application files should now live in a ``static`` directory in each app
(`django-staticfiles`_ used the name ``media``, which was slightly
confusing).
* Application files should now live in a ``static`` directory in each app
(`django-staticfiles`_ used the name ``media``, which was slightly
confusing).
* The management commands ``build_static`` and ``resolve_static`` are now
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
* The management commands ``build_static`` and ``resolve_static`` are now
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
removed.
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
removed.
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
new :setting:`STATICFILES_FINDERS`.
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
new :setting:`STATICFILES_FINDERS`.
* The default for :setting:`STATICFILES_STORAGE` was renamed from
``staticfiles.storage.StaticFileStorage`` to
``staticfiles.storage.StaticFilesStorage``
* The default for :setting:`STATICFILES_STORAGE` was renamed from
``staticfiles.storage.StaticFileStorage`` to
``staticfiles.storage.StaticFilesStorage``
* If using :ref:`runserver<staticfiles-runserver>` for local development
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
anything to your URLconf for serving static files in development.
* If using :ref:`runserver<staticfiles-runserver>` for local development
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
anything to your URLconf for serving static files in development.
Learn more
==========

View File

@ -34,190 +34,190 @@ Having trouble? We'd like to help!
First steps
===========
* **From scratch:**
:doc:`Overview <intro/overview>` |
:doc:`Installation <intro/install>`
* **From scratch:**
:doc:`Overview <intro/overview>` |
:doc:`Installation <intro/install>`
* **Tutorial:**
:doc:`Part 1 <intro/tutorial01>` |
:doc:`Part 2 <intro/tutorial02>` |
:doc:`Part 3 <intro/tutorial03>` |
:doc:`Part 4 <intro/tutorial04>`
* **Tutorial:**
:doc:`Part 1 <intro/tutorial01>` |
:doc:`Part 2 <intro/tutorial02>` |
:doc:`Part 3 <intro/tutorial03>` |
:doc:`Part 4 <intro/tutorial04>`
The model layer
===============
* **Models:**
:doc:`Model syntax <topics/db/models>` |
:doc:`Field types <ref/models/fields>` |
:doc:`Meta options <ref/models/options>`
* **Models:**
:doc:`Model syntax <topics/db/models>` |
:doc:`Field types <ref/models/fields>` |
:doc:`Meta options <ref/models/options>`
* **QuerySets:**
:doc:`Executing queries <topics/db/queries>` |
:doc:`QuerySet method reference <ref/models/querysets>`
* **QuerySets:**
:doc:`Executing queries <topics/db/queries>` |
:doc:`QuerySet method reference <ref/models/querysets>`
* **Model instances:**
:doc:`Instance methods <ref/models/instances>` |
:doc:`Accessing related objects <ref/models/relations>`
* **Model instances:**
:doc:`Instance methods <ref/models/instances>` |
:doc:`Accessing related objects <ref/models/relations>`
* **Advanced:**
:doc:`Managers <topics/db/managers>` |
:doc:`Raw SQL <topics/db/sql>` |
:doc:`Transactions <topics/db/transactions>` |
:doc:`Aggregation <topics/db/aggregation>` |
:doc:`Custom fields <howto/custom-model-fields>` |
:doc:`Multiple databases <topics/db/multi-db>`
* **Advanced:**
:doc:`Managers <topics/db/managers>` |
:doc:`Raw SQL <topics/db/sql>` |
:doc:`Transactions <topics/db/transactions>` |
:doc:`Aggregation <topics/db/aggregation>` |
:doc:`Custom fields <howto/custom-model-fields>` |
:doc:`Multiple databases <topics/db/multi-db>`
* **Other:**
:doc:`Supported databases <ref/databases>` |
:doc:`Legacy databases <howto/legacy-databases>` |
:doc:`Providing initial data <howto/initial-data>` |
:doc:`Optimize database access <topics/db/optimization>`
* **Other:**
:doc:`Supported databases <ref/databases>` |
:doc:`Legacy databases <howto/legacy-databases>` |
:doc:`Providing initial data <howto/initial-data>` |
:doc:`Optimize database access <topics/db/optimization>`
The template layer
==================
* **For designers:**
:doc:`Syntax overview <topics/templates>` |
:doc:`Built-in tags and filters <ref/templates/builtins>`
* **For designers:**
:doc:`Syntax overview <topics/templates>` |
:doc:`Built-in tags and filters <ref/templates/builtins>`
* **For programmers:**
:doc:`Template API <ref/templates/api>` |
:doc:`Custom tags and filters <howto/custom-template-tags>`
* **For programmers:**
:doc:`Template API <ref/templates/api>` |
:doc:`Custom tags and filters <howto/custom-template-tags>`
The view layer
==============
* **The basics:**
:doc:`URLconfs <topics/http/urls>` |
:doc:`View functions <topics/http/views>` |
:doc:`Shortcuts <topics/http/shortcuts>` |
:doc:`Decorators <topics/http/decorators>`
* **The basics:**
:doc:`URLconfs <topics/http/urls>` |
:doc:`View functions <topics/http/views>` |
:doc:`Shortcuts <topics/http/shortcuts>` |
:doc:`Decorators <topics/http/decorators>`
* **Reference:**
:doc:`Request/response objects <ref/request-response>` |
:doc:`TemplateResponse objects <ref/template-response>`
* **Reference:**
:doc:`Request/response objects <ref/request-response>` |
:doc:`TemplateResponse objects <ref/template-response>`
* **File uploads:**
:doc:`Overview <topics/http/file-uploads>` |
:doc:`File objects <ref/files/file>` |
:doc:`Storage API <ref/files/storage>` |
:doc:`Managing files <topics/files>` |
:doc:`Custom storage <howto/custom-file-storage>`
* **File uploads:**
:doc:`Overview <topics/http/file-uploads>` |
:doc:`File objects <ref/files/file>` |
:doc:`Storage API <ref/files/storage>` |
:doc:`Managing files <topics/files>` |
:doc:`Custom storage <howto/custom-file-storage>`
* **Generic views:**
:doc:`Overview<topics/class-based-views>` |
:doc:`Built-in generic views<ref/class-based-views>`
* **Generic views:**
:doc:`Overview<topics/class-based-views>` |
:doc:`Built-in generic views<ref/class-based-views>`
* **Advanced:**
:doc:`Generating CSV <howto/outputting-csv>` |
:doc:`Generating PDF <howto/outputting-pdf>`
* **Advanced:**
:doc:`Generating CSV <howto/outputting-csv>` |
:doc:`Generating PDF <howto/outputting-pdf>`
* **Middleware:**
:doc:`Overview <topics/http/middleware>` |
:doc:`Built-in middleware classes <ref/middleware>`
* **Middleware:**
:doc:`Overview <topics/http/middleware>` |
:doc:`Built-in middleware classes <ref/middleware>`
Forms
=====
* **The basics:**
:doc:`Overview <topics/forms/index>` |
:doc:`Form API <ref/forms/api>` |
:doc:`Built-in fields <ref/forms/fields>` |
:doc:`Built-in widgets <ref/forms/widgets>`
* **The basics:**
:doc:`Overview <topics/forms/index>` |
:doc:`Form API <ref/forms/api>` |
:doc:`Built-in fields <ref/forms/fields>` |
:doc:`Built-in widgets <ref/forms/widgets>`
* **Advanced:**
:doc:`Forms for models <topics/forms/modelforms>` |
:doc:`Integrating media <topics/forms/media>` |
:doc:`Formsets <topics/forms/formsets>` |
:doc:`Customizing validation <ref/forms/validation>`
* **Advanced:**
:doc:`Forms for models <topics/forms/modelforms>` |
:doc:`Integrating media <topics/forms/media>` |
:doc:`Formsets <topics/forms/formsets>` |
:doc:`Customizing validation <ref/forms/validation>`
* **Extras:**
:doc:`Form preview <ref/contrib/formtools/form-preview>` |
:doc:`Form wizard <ref/contrib/formtools/form-wizard>`
* **Extras:**
:doc:`Form preview <ref/contrib/formtools/form-preview>` |
:doc:`Form wizard <ref/contrib/formtools/form-wizard>`
The development process
=======================
* **Settings:**
:doc:`Overview <topics/settings>` |
:doc:`Full list of settings <ref/settings>`
* **Settings:**
:doc:`Overview <topics/settings>` |
:doc:`Full list of settings <ref/settings>`
* **Exceptions:**
:doc:`Overview <ref/exceptions>`
* **Exceptions:**
:doc:`Overview <ref/exceptions>`
* **django-admin.py and manage.py:**
:doc:`Overview <ref/django-admin>` |
:doc:`Adding custom commands <howto/custom-management-commands>`
* **django-admin.py and manage.py:**
:doc:`Overview <ref/django-admin>` |
:doc:`Adding custom commands <howto/custom-management-commands>`
* **Testing:** :doc:`Overview <topics/testing>`
* **Testing:** :doc:`Overview <topics/testing>`
* **Deployment:**
:doc:`Overview <howto/deployment/index>` |
:doc:`Apache/mod_wsgi <howto/deployment/modwsgi>` |
:doc:`uWSGI <howto/deployment/uwsgi>` |
:doc:`Apache/mod_python (deprecated) <howto/deployment/modpython>` |
:doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` |
:doc:`Apache authentication <howto/apache-auth>` |
:doc:`Handling static files <howto/static-files>` |
:doc:`Tracking code errors by email <howto/error-reporting>`
* **Deployment:**
:doc:`Overview <howto/deployment/index>` |
:doc:`Apache/mod_wsgi <howto/deployment/modwsgi>` |
:doc:`uWSGI <howto/deployment/uwsgi>` |
:doc:`Apache/mod_python (deprecated) <howto/deployment/modpython>` |
:doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` |
:doc:`Apache authentication <howto/apache-auth>` |
:doc:`Handling static files <howto/static-files>` |
:doc:`Tracking code errors by email <howto/error-reporting>`
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:`Authentication <topics/auth>`
* :doc:`Cache system <topics/cache>`
* :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:`Conditional content processing <topics/conditional-view-processing>`
* :doc:`Content types <ref/contrib/contenttypes>`
* :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>`
* :doc:`Cryptographic signing <topics/signing>`
* :doc:`Databrowse <ref/contrib/databrowse>`
* :doc:`E-mail (sending) <topics/email>`
* :doc:`Flatpages <ref/contrib/flatpages>`
* :doc:`GeoDjango <ref/contrib/gis/index>`
* :doc:`Humanize <ref/contrib/humanize>`
* :doc:`Internationalization <topics/i18n/index>`
* :doc:`Jython support <howto/jython>`
* :doc:`"Local flavor" <ref/contrib/localflavor>`
* :doc:`Logging <topics/logging>`
* :doc:`Messages <ref/contrib/messages>`
* :doc:`Pagination <topics/pagination>`
* :doc:`Redirects <ref/contrib/redirects>`
* :doc:`Security <topics/security>`
* :doc:`Serialization <topics/serialization>`
* :doc:`Sessions <topics/http/sessions>`
* :doc:`Signals <topics/signals>`
* :doc:`Sitemaps <ref/contrib/sitemaps>`
* :doc:`Sites <ref/contrib/sites>`
* :doc:`Static Files <ref/contrib/staticfiles>`
* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
* :doc:`Unicode in Django <ref/unicode>`
* :doc:`Web design helpers <ref/contrib/webdesign>`
* :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>`
* :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:`Cache system <topics/cache>`
* :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:`Conditional content processing <topics/conditional-view-processing>`
* :doc:`Content types <ref/contrib/contenttypes>`
* :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>`
* :doc:`Cryptographic signing <topics/signing>`
* :doc:`Databrowse <ref/contrib/databrowse>`
* :doc:`E-mail (sending) <topics/email>`
* :doc:`Flatpages <ref/contrib/flatpages>`
* :doc:`GeoDjango <ref/contrib/gis/index>`
* :doc:`Humanize <ref/contrib/humanize>`
* :doc:`Internationalization <topics/i18n/index>`
* :doc:`Jython support <howto/jython>`
* :doc:`"Local flavor" <ref/contrib/localflavor>`
* :doc:`Logging <topics/logging>`
* :doc:`Messages <ref/contrib/messages>`
* :doc:`Pagination <topics/pagination>`
* :doc:`Redirects <ref/contrib/redirects>`
* :doc:`Security <topics/security>`
* :doc:`Serialization <topics/serialization>`
* :doc:`Sessions <topics/http/sessions>`
* :doc:`Signals <topics/signals>`
* :doc:`Sitemaps <ref/contrib/sitemaps>`
* :doc:`Sites <ref/contrib/sites>`
* :doc:`Static Files <ref/contrib/staticfiles>`
* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
* :doc:`Unicode in Django <ref/unicode>`
* :doc:`Web design helpers <ref/contrib/webdesign>`
* :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>`
The Django open-source project
==============================
* **Community:**
:doc:`How to get involved <internals/contributing/index>` |
:doc:`The release process <internals/release-process>` |
:doc:`Team of committers <internals/committers>` |
:doc:`The Django source code repository <internals/svn>`
* **Community:**
:doc:`How to get involved <internals/contributing/index>` |
:doc:`The release process <internals/release-process>` |
:doc:`Team of committers <internals/committers>` |
:doc:`The Django source code repository <internals/svn>`
* **Design philosophies:**
:doc:`Overview <misc/design-philosophies>`
* **Design philosophies:**
:doc:`Overview <misc/design-philosophies>`
* **Documentation:**
:doc:`About this documentation <internals/contributing/writing-documentation>`
* **Documentation:**
:doc:`About this documentation <internals/contributing/writing-documentation>`
* **Third-party distributions:**
:doc:`Overview <misc/distributions>`
* **Third-party distributions:**
:doc:`Overview <misc/distributions>`
* **Django over time:**
:doc:`API stability <misc/api-stability>` |
:doc:`Release notes and upgrading instructions <releases/index>` |
:doc:`Deprecation Timeline <internals/deprecation>`
* **Django over time:**
:doc:`API stability <misc/api-stability>` |
:doc:`Release notes and upgrading instructions <releases/index>` |
: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
particular:
* **Do** read the :doc:`FAQ </faq/index>` to see if your issue might
be a well-known question.
* **Do** read the :doc:`FAQ </faq/index>` to see if your issue might
be a well-known question.
* **Do** ask on `django-users`_ or `#django`_ *first* if you're not sure if
what you're seeing is a bug.
* **Do** ask on `django-users`_ or `#django`_ *first* if you're not sure if
what you're seeing is a bug.
* **Do** write complete, reproducible, specific bug reports. You must
include a clear, concise description of the problem, and a set of
instructions for replicating it. Add as much debug information as you can:
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
way to confirm the bug quickly.
* **Do** write complete, reproducible, specific bug reports. You must
include a clear, concise description of the problem, and a set of
instructions for replicating it. Add as much debug information as you can:
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
way to confirm the bug quickly.
* **Don't** post to `django-developers`_ just to announce that you have
filed a bug report. All the tickets are mailed to another list,
`django-updates`_, which is tracked by developers and interested
community members; we see them as they are filed.
* **Don't** post to `django-developers`_ just to announce that you have
filed a bug report. All the tickets are mailed to another list,
`django-updates`_, which is tracked by developers and interested
community members; we see them as they are filed.
To understand the lifecycle of your ticket once you have created it, refer to
:doc:`triaging-tickets`.
@ -67,27 +67,27 @@ Reporting security issues
In the event of a confirmed vulnerability in Django itself, we will take the
following actions:
* 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
to keep the issue confidential until we announce it.
* 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
to keep the issue confidential until we announce it.
* Focus on developing a fix as quickly as possible and produce patches
against the current and two previous releases.
* Focus on developing a fix as quickly as possible and produce patches
against the current and two previous releases.
* Determine a go-public date for announcing the vulnerability and the fix.
To try to mitigate a possible "arms race" between those applying the
patch and those trying to exploit the hole, we will not announce
security problems immediately.
* Determine a go-public date for announcing the vulnerability and the fix.
To try to mitigate a possible "arms race" between those applying the
patch and those trying to exploit the hole, we will not announce
security problems immediately.
* Pre-notify third-party distributors of Django ("vendors"). We will send
these vendor notifications through private email which will include
documentation of the vulnerability, links to the relevant patch(es), and
a request to keep the vulnerability confidential until the official
go-public date.
* Pre-notify third-party distributors of Django ("vendors"). We will send
these vendor notifications through private email which will include
documentation of the vulnerability, links to the relevant patch(es), and
a request to keep the vulnerability confidential until the official
go-public date.
* Publicly announce the vulnerability and the fix on the pre-determined
go-public date. This will probably mean a new release of Django, but
in some cases it may simply be patches against current releases.
* Publicly announce the vulnerability and the fix on the pre-determined
go-public date. This will probably mean a new release of Django, but
in some cases it may simply be patches against current releases.
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
are a few additional guidelines to follow:
* Include screenshots in your ticket which are the visual equivalent of a
minimal testcase. Show off the issue, not the crazy customizations
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.
* Include screenshots in your ticket which are the visual equivalent of a
minimal testcase. Show off the issue, not the crazy customizations
you've made to your browser.
* 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.
* 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.
* Make sure to set the UI/UX flag on the ticket so interested parties can
find your ticket.
* 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
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
-------------------
@ -121,27 +121,27 @@ Requesting features
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:
* Make sure the feature actually requires changes in Django's core. If your
idea can be developed as an independent application or module — for
instance, you want to support another database engine — we'll probably
suggest that you to develop it independently. Then, if your project
gathers sufficient community support, we may consider it for inclusion in
Django.
* Make sure the feature actually requires changes in Django's core. If your
idea can be developed as an independent application or module — for
instance, you want to support another database engine — we'll probably
suggest that you to develop it independently. Then, if your project
gathers sufficient community support, we may consider it for inclusion in
Django.
* 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.
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
actually working on them.
* 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.
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
actually working on them.
* 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)
if possible.
* 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)
if possible.
* 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,
you'll need to explain it, if it isn't obvious why the feature would be
useful.
* 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,
you'll need to explain it, if it isn't obvious why the feature would be
useful.
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
@ -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
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
into reality."
* -1: "I strongly disagree and would be very unhappy to see the idea turn
into reality."
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
@ -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
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
positive or negative veto.
* The :ref:`BDFLs<django-bdfls>` haven't stepped in and executed their
positive or negative veto.
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

View File

@ -38,58 +38,58 @@ Committing guidelines
Please follow these guidelines when committing code to Django's Subversion
repository:
* For any medium-to-big changes, where "medium-to-big" is according to
your judgment, please bring things up on the `django-developers`_
mailing list before making the change.
* For any medium-to-big changes, where "medium-to-big" is according to
your judgment, please bring things up on the `django-developers`_
mailing list before making the change.
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
implemented immediately because nobody contested it. Django's lead
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
response.
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
implemented immediately because nobody contested it. Django's lead
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
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."
* Bad: "Fixes Unicode bug in RSS API."
* Bad: "Fixing Unicode bug in RSS API."
* Good: "Fixed Unicode bug in RSS API."
* Bad: "Fixes 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 example: "magic-removal: Added support for mind reading."
* For commits to a branch, prefix the commit message with the branch name.
For example: "magic-removal: Added support for mind reading."
* Limit commits to the most granular change that makes sense. This means,
use frequent small commits rather than infrequent large commits. For
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
separate commit. This goes a *long way* in helping all core Django
developers follow your changes.
* Limit commits to the most granular change that makes sense. This means,
use frequent small commits rather than infrequent large commits. For
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
separate commit. This goes a *long way* in helping all core Django
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
current trunk.
Bug fixes need to be added to the current bugfix branch as well as the
current trunk.
* If your commit closes a ticket in the Django `ticket tracker`_, begin
your commit message with the text "Fixed #abc", where "abc" is the
number of the ticket your commit fixes. Example: "Fixed #123 -- Added
support for foo". We've rigged Subversion and Trac so that any commit
message in that format will automatically close the referenced ticket
and post a comment to it with the full commit message.
* If your commit closes a ticket in the Django `ticket tracker`_, begin
your commit message with the text "Fixed #abc", where "abc" is the
number of the ticket your commit fixes. Example: "Fixed #123 -- Added
support for foo". We've rigged Subversion and Trac so that any commit
message in that format will automatically close the referenced ticket
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
first, then the "Fixed #abc." For example:
"magic-removal: Fixed #123 -- Added whizbang feature."
If your commit closes a ticket and is in a branch, use the branch name
first, then the "Fixed #abc." For example:
"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
does *not* close the ticket, include the phrase "Refs #abc", where "abc"
is the number of the ticket your commit references. We've rigged
Subversion and Trac so that any commit message in that format will
automatically post a comment to the appropriate ticket.
* If your commit references a ticket in the Django `ticket tracker`_ but
does *not* close the ticket, include the phrase "Refs #abc", where "abc"
is the number of the ticket your commit references. We've rigged
Subversion and Trac so that any commit message in that format will
automatically post a comment to the appropriate ticket.
Reverting commits
-----------------
@ -97,35 +97,35 @@ Reverting commits
Nobody's perfect; mistakes will be committed. When a mistaken commit is
discovered, please follow these guidelines:
* 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
the highest quality possible. Really: double-check your work before
you commit it in the first place!
* 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
the highest quality possible. Really: double-check your work before
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
original author.
* Don't revert another author's changes without permission from the
original author.
* 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,
major test failures, etc -- then ask for objections on the
`django-developers`_ mailing list then revert if there are none.
* 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,
major test failures, etc -- then ask for objections on the
`django-developers`_ mailing list then revert if there are none.
* If the problem is small (a feature commit after feature freeze,
say), wait it out.
* If the problem is small (a feature commit after feature freeze,
say), wait it out.
* If there's a disagreement between the committer and the
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
be put to a vote.
* If there's a disagreement between the committer and the
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
be put to a vote.
* If the commit introduced a confirmed, disclosed security
vulnerability then the commit may be reverted immediately without
permission from anyone.
* If the commit introduced a confirmed, disclosed security
vulnerability then the commit may be reverted immediately without
permission from anyone.
* The release branch maintainer may back out commits to the release
branch without permission if the commit breaks the release branch.
* The release branch maintainer may back out commits to the release
branch without permission if the commit breaks the release branch.
.. _django-developers: http://groups.google.com/group/django-developers
.. _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
contribute in many ways:
* Join the `django-users`_ mailing list and answer questions. This
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,
you should read the `posting guidelines`_.
* Join the `django-users`_ mailing list and answer questions. This
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,
you should read the `posting guidelines`_.
* 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
framework yourself.
* 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
framework yourself.
* 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
can `register it here`_.
* 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
can `register it here`_.
* Contribute to open-source Django projects, write some documentation, or
release your own code as an open-source pluggable application. The
ecosystem of pluggable applications is a big strength of Django, help us
build it!
* Contribute to open-source Django projects, write some documentation, or
release your own code as an open-source pluggable application. The
ecosystem of pluggable applications is a big strength of Django, help us
build it!
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
members of the community, so there are several ways you can help Django's
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
to improve Django. We're always open to suggestions.
* Join the `django-developers`_ mailing list and share your ideas for how
to improve Django. We're always open to suggestions.
* :doc:`Submit patches <writing-code/submitting-patches>` for new and/or
fixed behavior. If you're looking for an easy way to start contributing
to Django have a look at the `easy pickings`_ tickets.
* :doc:`Submit patches <writing-code/submitting-patches>` for new and/or
fixed behavior. If you're looking for an easy way to start contributing
to Django have a look at the `easy pickings`_ tickets.
* :doc:`Improve the documentation <writing-documentation>` or
:doc:`write unit tests <writing-code/unit-tests>`.
* :doc:`Improve the documentation <writing-documentation>` or
:doc:`write unit tests <writing-code/unit-tests>`.
* :doc:`Triage tickets and review patches <triaging-tickets>` created by
other users.
* :doc:`Triage tickets and review patches <triaging-tickets>` created by
other users.
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
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
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
and select the appropriate language.
* On the `translation teams`_ page, choose the language team you want
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
and select the appropriate language.
* 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
your membership request. You can of course also contact the team
coordinator to clarify procedural problems and handle the actual
translation process.
* 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
your membership request. You can of course also contact the team
coordinator to clarify procedural problems and handle the actual
translation process.
* 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
to the translation catalogue that contains all non-contrib translations.
Each of the contrib apps also have a resource (prefixed with "contrib").
* 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
to the translation catalogue that contains all non-contrib translations.
Each of the contrib apps also have a resource (prefixed with "contrib").
.. note::
For more information about how to use Transifex, read the
`Transifex User Guide`_.
.. note::
For more information about how to use Transifex, read the
`Transifex User Guide`_.
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
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
``Translations``, and attach the patch to it.
* Open a ticket in Django's ticket system, set its ``Component`` field to
``Translations``, and attach the patch to it.
.. _Transifex: http://www.transifex.net/
.. _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:
* :doc:`Committers</internals/committers>` (also called core developers):
people with commit access who are responsible for making the big
decisions, writing large portions of the code and integrating the
contributions of the community.
* :doc:`Committers</internals/committers>` (also called core developers):
people with commit access who are responsible for making the big
decisions, writing large portions of the code and integrating the
contributions of the community.
* Ticket triagers: anyone in the Django community who chooses to
become involved in Django's development process. Our Trac installation
is intentionally left open to the public, and anyone can triage tickets.
Django is a community project, and we encourage :ref:`triage by the
community<how-can-i-help-with-triaging>`.
* Ticket triagers: anyone in the Django community who chooses to
become involved in Django's development process. Our Trac installation
is intentionally left open to the public, and anyone can triage tickets.
Django is a community project, and we encourage :ref:`triage by the
community<how-can-i-help-with-triaging>`.
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:
* Has patch
This means the ticket has an associated
:doc:`patch<writing-code/submitting-patches>`. These will be reviewed
to see if the patch is "good".
* Needs documentation:
This flag is used for tickets with patches that need associated
documentation. Complete documentation of features is a prerequisite
before we can check them into the codebase.
* Needs tests
This flags the patch as needing associated unit tests. Again, this
is a required part of a valid patch.
* Patch needs improvement
This flag means that although the ticket *has* a patch, it's not quite
ready for checkin. This could mean the patch no longer applies
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.
* Has patch
This means the ticket has an associated
:doc:`patch<writing-code/submitting-patches>`. These will be reviewed
to see if the patch is "good".
* Needs documentation:
This flag is used for tickets with patches that need associated
documentation. Complete documentation of features is a prerequisite
before we can check them into the codebase.
* Needs tests
This flags the patch as needing associated unit tests. Again, this
is a required part of a valid patch.
* Patch needs improvement
This flag means that although the ticket *has* a patch, it's not quite
ready for checkin. This could mean the patch no longer applies
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:
* New Feature
For adding something new.
* New Feature
For adding something new.
* Bug
For when an existing thing is broken or not behaving as expected.
* Bug
For when an existing thing is broken or not behaving as expected.
* Cleanup/optimization
For when nothing is broken but something could be made cleaner,
better, faster, stronger.
* Cleanup/optimization
For when nothing is broken but something could be made cleaner,
better, faster, stronger.
Tickets should also be classified into *components* indicating which area of
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:
* 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
cross-reference the closed ticket by leaving a comment in the original one
-- this allows to access more related information about the reported bug
or requested feature.
* If the ticket is a duplicate, reference the original ticket. Also
cross-reference the closed ticket by leaving a comment in the original one
-- this allows to access more related information about the reported bug
or requested feature.
* **Be polite.** No one likes having their ticket closed. It can be
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
suggestions for how they could improve this ticket and other tickets in
the future.
* **Be polite.** No one likes having their ticket closed. It can be
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
suggestions for how they could improve this ticket and other tickets in
the future.
A ticket can be resolved in a number of ways:
* fixed
Used by the core developers once a patch has been rolled into
Django and the issue is fixed.
* fixed
Used by the core developers once a patch has been rolled into
Django and the issue is fixed.
* invalid
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
describes a problem with something other than Django, or isn't
a bug report or feature request at all (for example, some new users
submit support queries as tickets).
* invalid
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
describes a problem with something other than Django, or isn't
a bug report or feature request at all (for example, some new users
submit support queries as tickets).
* wontfix
Used when a core developer decides that this request is not
appropriate for consideration in Django. This is usually chosen after
discussion in the `django-developers`_ mailing list. Feel free to
start or join in discussions of "wontfix" tickets on the
django-developers_ mailing list, but please do not reopen tickets
closed as "wontfix" by a :doc:`core developer</internals/committers>`.
* wontfix
Used when a core developer decides that this request is not
appropriate for consideration in Django. This is usually chosen after
discussion in the `django-developers`_ mailing list. Feel free to
start or join in discussions of "wontfix" tickets on the
django-developers_ mailing list, but please do not reopen tickets
closed as "wontfix" by a :doc:`core developer</internals/committers>`.
* duplicate
Used when another ticket covers the same issue. By closing duplicate
tickets, we keep all the discussion in one place, which helps
everyone.
* duplicate
Used when another ticket covers the same issue. By closing duplicate
tickets, we keep all the discussion in one place, which helps
everyone.
* worksforme
Used when the ticket doesn't contain enough detail to replicate
the original bug.
* worksforme
Used when the ticket doesn't contain enough detail to replicate
the original bug.
* needsinfo
Used when the ticket does not contain enough information to replicate
the reported issue but is potentially still valid. The ticket
should be reopened when more information is supplied.
* needsinfo
Used when the ticket does not contain enough information to replicate
the reported issue but is potentially still valid. The ticket
should be reopened when more information is supplied.
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
@ -315,39 +319,39 @@ forgotten your password, you can reset it using the `password reset page`_.
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
decision needs to be made, or "Accepted" in case of obvious bugs or
sensible, clearly defined, feature requests.
* Promoting "Unreviewed" tickets to "Design decision needed" if a design
decision needs to be made, or "Accepted" in case of obvious bugs or
sensible, clearly defined, feature requests.
* Correcting the "Needs tests", "Needs documentation", or "Has patch"
flags for tickets where they are incorrectly set.
* Correcting the "Needs tests", "Needs documentation", or "Has patch"
flags for tickets where they are incorrectly set.
* Setting the "`Easy pickings`_" flag for tickets that are small and
relatively straightforward.
* Setting the "`Easy pickings`_" flag for tickets that are small and
relatively straightforward.
* 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
fixed but the ticket hasn't yet been closed.
* 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
fixed but the ticket hasn't yet been closed.
* 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
or so, remove the owner's claim on the ticket.
* 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
or so, remove the owner's claim on the ticket.
* 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
consider refactoring that part of the code. If a trend is emerging,
you should raise it for discussion (referencing the relevant tickets)
on `django-developers`_.
* 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
consider refactoring that part of the code. If a trend is emerging,
you should raise it for discussion (referencing the relevant tickets)
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
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
why and set the corresponding flags ("Patch needs improvement",
"Needs tests" etc.).
* Verify if patches submitted by other users are correct. If they do and
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
why and set the corresponding flags ("Patch needs improvement",
"Needs tests" etc.).
.. note::
@ -362,23 +366,23 @@ Then, you can help out by:
However, we do ask the following of all general community members working in
the ticket database:
* Please **don't** close tickets as "wontfix." The core developers will
make the final determination of the fate of a ticket, usually after
consultation with the community.
* Please **don't** close tickets as "wontfix." The core developers will
make the final determination of the fate of a ticket, usually after
consultation with the community.
* 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
checkin", but you should get at minimum one other community member to
review a patch that you submit.
* 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
checkin", but you should get at minimum one other community member to
review a patch that you submit.
* Please **don't** reverse a decision that has been made by a :doc:`core
developer</internals/committers>`. If you disagree with a decision that
has been made, please post a message to `django-developers`_.
* Please **don't** reverse a decision that has been made by a :doc:`core
developer</internals/committers>`. If you disagree with a decision that
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
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,
but your input is still valuable.
* 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,
or post a message to `django-developers`_. It's okay to be unsure,
but your input is still valuable.
.. _Trac: http://code.djangoproject.com/
.. _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
for feature branches:
1. Feature branches using a distributed revision control system like
Git_, Mercurial_, Bazaar_, etc.
1. Feature branches using a distributed revision control system like
Git_, Mercurial_, Bazaar_, etc.
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
core developers.
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
core developers.
However, do keep in mind that Django will continue to use Subversion
for the foreseeable future, and this will naturally limit the
recognition of your branch. Further, if your branch becomes eligible
for merging to trunk you'll need to find a core developer familiar
with your DVCS of choice who'll actually perform the merge.
However, do keep in mind that Django will continue to use Subversion
for the foreseeable future, and this will naturally limit the
recognition of your branch. Further, if your branch becomes eligible
for merging to trunk you'll need to find a core developer familiar
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
make it public, please add the branch to the `Django branches`_ wiki
page.
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
page.
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
</internals/committers>`. This person is responsible for actually
creating the branch, monitoring your process (see below), and
ultimately merging the branch into trunk.
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
</internals/committers>`. This person is responsible for actually
creating the branch, monitoring your process (see below), and
ultimately merging the branch into trunk.
If you want a feature branch in SVN, you'll need to ask in
`django-developers`_ for a mentor.
If you want a feature branch in SVN, you'll need to ask in
`django-developers`_ for a mentor.
.. _git: http://git-scm.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
rules are broken.
* 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
branch.
* 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
branch.
* Merge changes from trunk no less than once a week, and preferably every
couple-three days.
* Merge changes from trunk no less than once a week, and preferably every
couple-three days.
In our experience, doing regular trunk merges is often the difference
between a successful branch and one that fizzles and dies.
In our experience, doing regular trunk merges is often the difference
between a successful branch and one that fizzles and dies.
If you're working on an SVN branch, you should be using `svnmerge.py`_
to track merges from trunk.
If you're working on an SVN branch, you should be using `svnmerge.py`_
to track merges from trunk.
* Keep tests passing and documentation up-to-date. As with patches,
we'll only merge a branch that comes with tests and documentation.
* Keep tests passing and documentation up-to-date. As with patches,
we'll only merge a branch that comes with tests and documentation.
.. _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:
* 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
the ``django`` package rather than the version you already have
installed.
* Point your Python ``site-packages`` directory at the branch's version of
the ``django`` package rather than the version you already have
installed.
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
------------
* 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
area, but remember that :pep:`8` is only a guide, so respect the style of
the surrounding code as a primary goal.
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
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
(i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``).
* Use underscores, not camelCase, for variable, function and method names
(i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``).
* Use ``InitialCaps`` for class names (or for factory functions that
return classes).
* Use ``InitialCaps`` for class names (or for factory functions that
return classes).
* In docstrings, use "action words" such as::
* In docstrings, use "action words" such as::
def foo():
"""
Calculates something and returns the result.
"""
pass
def foo():
"""
Calculates something and returns the result.
"""
pass
Here's an example of what not to do::
Here's an example of what not to do::
def foo():
"""
Calculate something and return the result.
"""
pass
def foo():
"""
Calculate something and return the result.
"""
pass
Template style
--------------
* In Django template code, put one (and only one) space between the curly
brackets and the tag contents.
* In Django template code, put one (and only one) space between the curly
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
----------
* In Django views, the first parameter in a view function should be called
``request``.
* In Django views, the first parameter in a view function should be called
``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
-----------
* Field names should be all lowercase, using underscores instead of
camelCase.
* Field names should be all lowercase, using underscores instead of
camelCase.
Do this::
Do this::
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
Don't do this::
Don't do this::
class Person(models.Model):
FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40)
class Person(models.Model):
FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40)
* The ``class Meta`` should appear *after* the fields are defined, with
a single blank line separating the fields and the class definition.
* The ``class Meta`` should appear *after* the fields are defined, with
a single blank line separating the fields and the class definition.
Do this::
Do this::
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
class Meta:
verbose_name_plural = 'people'
Don't do this::
Don't do this::
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
Don't do this, either::
Don't do this, either::
class Person(models.Model):
class Meta:
verbose_name_plural = 'people'
class Person(models.Model):
class Meta:
verbose_name_plural = 'people'
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
* The order of model inner classes and standard methods should be as
follows (noting that these are not all required):
* The order of model inner classes and standard methods should be as
follows (noting that these are not all required):
* All database fields
* Custom manager attributes
* ``class Meta``
* ``def __unicode__()``
* ``def __str__()``
* ``def save()``
* ``def get_absolute_url()``
* Any custom methods
* All database fields
* Custom manager attributes
* ``class Meta``
* ``def __unicode__()``
* ``def __str__()``
* ``def save()``
* ``def get_absolute_url()``
* Any custom methods
* 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
the model module or just above the model class. Example::
* 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
the model module or just above the model class. Example::
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
Use of ``django.conf.settings``
-------------------------------
@ -178,26 +178,26 @@ as :class:`django.utils.functional.LazyObject`,
Miscellaneous
-------------
* Mark all strings for internationalization; see the :doc:`i18n
documentation </topics/i18n/index>` for details.
* Mark all strings for internationalization; see the :doc:`i18n
documentation </topics/i18n/index>` for details.
* Remove ``import`` statements that are no longer used when you change code.
The most common tools for this task are `pyflakes`_ and `pylint`_.
* Remove ``import`` statements that are no longer used when you change code.
The most common tools for this task are `pyflakes`_ and `pylint`_.
* Systematically remove all trailing whitespaces from your code as those
add unnecessary bytes, add visual clutter to the patches and can also
occasionally cause unnecessary merge conflicts. Some IDE's can be
configured to automatically remove them and most VCS tools can be set to
highlight them in diff outputs. Note, however, that patches which only
remove whitespace (or only make changes for nominal PEP 8 conformance)
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.
* Systematically remove all trailing whitespaces from your code as those
add unnecessary bytes, add visual clutter to the patches and can also
occasionally cause unnecessary merge conflicts. Some IDE's can be
configured to automatically remove them and most VCS tools can be set to
highlight them in diff outputs. Note, however, that patches which only
remove whitespace (or only make changes for nominal PEP 8 conformance)
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.
* 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
-- 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
single trivial change.
* 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
-- 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
single trivial change.
.. _pep8: http://pypi.python.org/pypi/pep8
.. _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
and time availability), claim it by following these steps:
* `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
`password reset page`_.
* `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
`password reset page`_.
* If a ticket for this issue doesn't exist yet, create one in our
`ticket tracker`_.
* If a ticket for this issue doesn't exist yet, create one in our
`ticket tracker`_.
* 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.
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
another bug/feature to work on, or contact the developer working on the
ticket to offer your help.
* 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.
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
another bug/feature to work on, or contact the developer working on the
ticket to offer your help.
* Log into your account, if you haven't already, by clicking "Login" in
the upper right of the ticket page.
* Log into your account, if you haven't already, by clicking "Login" in
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
page,
2. then click "Submit changes."
1. click the "accept" radio button under "Action" near the bottom of the
page,
2. then click "Submit changes."
.. _Create an account: https://www.djangoproject.com/accounts/register/
.. _password reset page: https://www.djangoproject.com/accounts/password/reset/
@ -76,43 +76,43 @@ it.
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.
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
hard to read patches when the only difference in code is that it's
indented.
* Submit patches in the format returned by the ``svn diff`` command.
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
hard to read patches when the only difference in code is that it's
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
``trunk`` directory -- i.e. the one that contains ``django``, ``docs``,
``tests``, ``AUTHORS``, etc. This makes it easy for other people to
apply your patches.
* When creating patches, always run ``svn diff`` from the top-level
``trunk`` directory -- i.e. the one that contains ``django``, ``docs``,
``tests``, ``AUTHORS``, etc. This makes it easy for other people to
apply your patches.
* Attach patches to a ticket in the `ticket tracker`_, using the "attach
file" button. Please *don't* put the patch in the ticket description
or comment unless it's a single line patch.
* Attach patches to a ticket in the `ticket tracker`_, using the "attach
file" button. Please *don't* put the patch in the ticket description
or comment unless it's a single line patch.
* Name the patch file with a ``.diff`` extension; this will let the ticket
tracker apply correct syntax highlighting, which is quite helpful.
* Name the patch file with a ``.diff`` extension; this will let the ticket
tracker apply correct syntax highlighting, which is quite helpful.
* 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
the `list of tickets with patches`_.
* 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
the `list of tickets with patches`_.
* 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
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
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
discussions after your patch gets committed and the tickets get closed.
* 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
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
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
discussions after your patch gets committed and the tickets get closed.
* If the code associated with a patch adds a new feature, or modifies
behavior of an existing feature, the patch should also contain
documentation.
* If the code associated with a patch adds a new feature, or modifies
behavior of an existing feature, the patch should also contain
documentation.
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:
* Models and the database API (``tests/modeltests``),
* Everything else in core Django code (``tests/regressiontests``),
* :ref:`contrib-apps` (``django/contrib/<app>/tests``).
* Models and the database API (``tests/modeltests``),
* Everything else in core Django code (``tests/regressiontests``),
* :ref:`contrib-apps` (``django/contrib/<app>/tests``).
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
two databases:
* A ``default`` database. This database should use the backend that
you want to use for primary testing
* A ``default`` database. This database should use the backend that
you want to use for primary testing
* A database with the alias ``other``. The ``other`` database is
used to establish that queries can be directed to different
databases. As a result, this database can use any backend you
want. It doesn't need to use the same backend as the ``default``
database (although it can use the same backend if you want to).
* A database with the alias ``other``. The ``other`` database is
used to establish that queries can be directed to different
databases. As a result, this database can use any backend you
want. It doesn't need to use the same backend as the ``default``
database (although it can use the same backend if you want to).
If you're using a backend that isn't SQLite, you will need to provide other
details for each database:
* The :setting:`USER` option for each of your databases needs to
specify an existing user account for the database.
* The :setting:`USER` option for each of your databases needs to
specify an existing user account for the database.
* The :setting:`PASSWORD` option needs to provide the password for
the :setting:`USER` that has been specified.
* The :setting:`PASSWORD` option needs to provide the password for
the :setting:`USER` that has been specified.
* The :setting:`NAME` option must be the name of an existing database to
which the given user has permission to connect. The unit tests will not
touch this database; the test runner creates a new database whose name
is :setting:`NAME` prefixed with ``test_``, and this test database is
deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``.
* The :setting:`NAME` option must be the name of an existing database to
which the given user has permission to connect. The unit tests will not
touch this database; the test runner creates a new database whose name
is :setting:`NAME` prefixed with ``test_``, and this test database is
deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``.
You will also need to ensure that your database uses UTF-8 as the default
character set. If your database server doesn't use UTF-8 as a default charset,
@ -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
dependencies:
* PyYAML_
* Markdown_
* Textile_
* Docutils_
* setuptools_
* memcached_, plus a :ref:`supported Python binding <memcached>`
* gettext_ (:ref:`gettext_on_windows`)
* PyYAML_
* Markdown_
* Textile_
* Docutils_
* setuptools_
* memcached_, plus a :ref:`supported Python binding <memcached>`
* gettext_ (:ref:`gettext_on_windows`)
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.

View File

@ -9,11 +9,11 @@ possible.
Documentation changes generally come in two forms:
* General improvements: typo corrections, error fixes and better
explanations through clearer writing and more examples.
* General improvements: typo corrections, error fixes and better
explanations through clearer writing and more examples.
* New features: documentation of features that have been added to the
framework since the last release.
* New features: documentation of features that have been added to the
framework since the last release.
This section explains how writers can craft their documentation changes
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
documentation:
* **Django** -- when referring to the framework, capitalize Django. It is
lowercase only in Python code and in the djangoproject.com logo.
* **Django** -- when referring to the framework, capitalize Django. It is
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
"ize" suffix, not "ise."
* **realize**, **customize**, **initialize**, etc. -- use the American
"ize" suffix, not "ise."
* **subclass** -- it's a single word without a hyphen, both as a verb
("subclass that model") and as a noun ("create a subclass").
* **subclass** -- it's a single word without a hyphen, both as a verb
("subclass that model") and as a noun ("create a subclass").
* **Web**, **World Wide Web**, **the Web** -- note Web is always
capitalized when referring to the World Wide Web.
* **Web**, **World Wide Web**, **the Web** -- note Web is always
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
---------------------------
* **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
"conf."
* **URLconf** -- use three capitalized letters, with no space before
"conf."
* **view** -- it's not capitalized.
* **view** -- it's not capitalized.
Guidelines for reStructuredText files
-------------------------------------
@ -92,27 +92,27 @@ Guidelines for reStructuredText files
These guidelines regulate the format of our reST (reStructuredText)
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
is significantly less readable when split over two lines, or for another
good reason.
* Wrap the documentation at 80 characters wide, unless a code example
is significantly less readable when split over two lines, or for another
good reason.
* 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::
* 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::
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
greatly helps readers. There's basically no limit to the amount of
useful markup you can add.
This is because Sphinx will generate proper links for the latter, which
greatly helps readers. There's basically no limit to the amount of
useful markup you can add.
* Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx'
documentation.
* Use :mod:`~sphinx.ext.intersphinx` to reference Python's and Sphinx'
documentation.
Django-specific markup
----------------------
@ -122,41 +122,41 @@ description units:
__ 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:
@ -184,68 +184,68 @@ An example
For a quick example of how it all fits together, consider this hypothetical
example:
* First, the ``ref/settings.txt`` document could have an overall layout
like this:
* First, the ``ref/settings.txt`` document could have an overall layout
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
this:
* Next, the ``topics/settings.txt`` document could contain something like
this:
.. code-block:: rst
.. code-block:: rst
You can access a :ref:`listing of all available settings
<available-settings>`. For a list of deprecated settings see
:ref:`deprecated-settings`.
You can access a :ref:`listing of all available settings
<available-settings>`. For a list of deprecated settings see
:ref:`deprecated-settings`.
You can find both in the :doc:`settings reference document
</ref/settings>`.
You can find both in the :doc:`settings reference document
</ref/settings>`.
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
we want to link to an arbitrary location in a document.
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
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
settings modules (in the format ``'foo.bar.baz'``) for which this site
is an admin.
Used for admin-site settings modules, this should be a tuple of
settings modules (in the format ``'foo.bar.baz'``) for which this site
is an admin.
The admin site uses this in its automatically-introspected
documentation of models, views and template tags.
The admin site uses this in its automatically-introspected
documentation of models, views and template tags.
This marks up the following header as the "canonical" target for the
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``,
I can reference it using ``:setting:`ADMIN_FOR```.
This marks up the following header as the "canonical" target for the
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``,
I can reference it using ``:setting:`ADMIN_FOR```.
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
look better:
* Most of the various ``index.txt`` documents have *very* short or even
non-existent intro text. Each of those documents needs a good short
intro the content below that point.
* Most of the various ``index.txt`` documents have *very* short or even
non-existent intro text. Each of those documents needs a good short
intro the content below that point.
* 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
right now can probably be turned into a xref.
* Add more links -- nearly everything that's an inline code literal
right now can probably be turned into a xref.
See the ``literals_to_xrefs.py`` file in ``_ext`` -- it's a shell script
to help do this work.
See the ``literals_to_xrefs.py`` file in ``_ext`` -- it's a shell script
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
of ````ADMIN_FOR````.
* Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead
of ````ADMIN_FOR````.
* Use directives where appropriate. Some directives
(e.g. ``.. setting::``) are prefix-style directives; they go *before*
the unit they're describing. These are known as "crossref" directives.
Others (e.g. ``.. class::``) generate their own markup; these should go
inside the section they're describing. These are called
"description units".
* Use directives where appropriate. Some directives
(e.g. ``.. setting::``) are prefix-style directives; they go *before*
the unit they're describing. These are known as "crossref" directives.
Others (e.g. ``.. class::``) generate their own markup; these should go
inside the section they're describing. These are called
"description units".
You can tell which are which by looking at in
:file:`_ext/djangodocs.py`; it registers roles as one of the other.
You can tell which are which by looking at in
:file:`_ext/djangodocs.py`; it registers roles as one of the other.
* Add ``.. code-block:: <lang>`` to literal blocks so that they get
highlighted.
* Add ``.. code-block:: <lang>`` to literal blocks so that they get
highlighted.
* When referring to classes/functions/modules, etc., you'll want to use
the fully-qualified name of the target
(``:class:`django.contrib.contenttypes.models.ContentType```).
* When referring to classes/functions/modules, etc., you'll want to use
the fully-qualified name of the target
(``:class:`django.contrib.contenttypes.models.ContentType```).
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 ``~``
(that's a tilde) to get just the "last bit" of that path. So
``:class:`~django.contrib.contenttypes.models.ContentType``` will just
display a link with the title "ContentType".
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 ``~``
(that's a tilde) to get just the "last bit" of that path. So
``:class:`~django.contrib.contenttypes.models.ContentType``` will just
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
these changes.
* ``AdminSite.root()``. This method of hooking up the admin URLs will be
removed in favor of including ``admin.site.urls``.
* ``AdminSite.root()``. This method of hooking up the admin URLs will be
removed in favor of including ``admin.site.urls``.
* Authentication backends need to define the boolean attributes
``supports_object_permissions`` and ``supports_anonymous_user`` until
version 1.4, at which point it will be assumed that all backends will
support these options.
* Authentication backends need to define the boolean attributes
``supports_object_permissions`` and ``supports_anonymous_user`` until
version 1.4, at which point it will be assumed that all backends will
support these options.
1.4
---
@ -27,92 +27,92 @@ these changes.
See the :doc:`Django 1.2 release notes</releases/1.2>` for more details on
these changes.
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed. Use
the {% csrf_token %} template tag inside forms to enable CSRF
protection. ``CsrfViewMiddleware`` remains and is enabled by default.
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed. Use
the {% csrf_token %} template tag inside forms to enable CSRF
protection. ``CsrfViewMiddleware`` remains and is enabled by default.
* The old imports for CSRF functionality (``django.contrib.csrf.*``),
which moved to core in 1.2, will be removed.
* The old imports for CSRF functionality (``django.contrib.csrf.*``),
which moved to core in 1.2, will be removed.
* The :mod:`django.contrib.gis.db.backend` module will be removed in favor
of the specific backends.
* The :mod:`django.contrib.gis.db.backend` module will be removed in favor
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
will be removed.
* The many to many SQL generation functions on the database backends
will be removed.
* The ability to use the ``DATABASE_*`` family of top-level settings to
define database connections will be removed.
* The ability to use the ``DATABASE_*`` family of top-level settings to
define database connections will be removed.
* The ability to use shorthand notation to specify a database backend
(i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be
removed.
* The ability to use shorthand notation to specify a database backend
(i.e., ``sqlite3`` instead of ``django.db.backends.sqlite3``) will be
removed.
* The ``get_db_prep_save``, ``get_db_prep_value`` and
``get_db_prep_lookup`` methods will have to support multiple databases.
* The ``get_db_prep_save``, ``get_db_prep_value`` and
``get_db_prep_lookup`` methods will have to support multiple databases.
* The ``Message`` model (in ``django.contrib.auth``), its related
manager in the ``User`` model (``user.message_set``), and the
associated methods (``user.message_set.create()`` and
``user.get_and_delete_messages()``), will be removed. The
:doc:`messages framework </ref/contrib/messages>` should be used
instead. The related ``messages`` variable returned by the
auth context processor will also be removed. Note that this
means that the admin application will depend on the messages
context processor.
* The ``Message`` model (in ``django.contrib.auth``), its related
manager in the ``User`` model (``user.message_set``), and the
associated methods (``user.message_set.create()`` and
``user.get_and_delete_messages()``), will be removed. The
:doc:`messages framework </ref/contrib/messages>` should be used
instead. The related ``messages`` variable returned by the
auth context processor will also be removed. Note that this
means that the admin application will depend on the messages
context processor.
* Authentication backends will need to support the ``obj`` parameter for
permission checking. The ``supports_object_permissions`` attribute
will no longer be checked and can be removed from custom backends.
* Authentication backends will need to support the ``obj`` parameter for
permission checking. The ``supports_object_permissions`` attribute
will no longer be checked and can be removed from custom backends.
* Authentication backends will need to support the ``AnonymousUser`` class
being passed to all methods dealing with permissions. The
``supports_anonymous_user`` variable will no longer be checked and can be
removed from custom backends.
* Authentication backends will need to support the ``AnonymousUser`` class
being passed to all methods dealing with permissions. The
``supports_anonymous_user`` variable will no longer be checked and can be
removed from custom backends.
* The ability to specify a callable template loader rather than a
``Loader`` class will be removed, as will the ``load_template_source``
functions that are included with the built in template loaders for
backwards compatibility.
* The ability to specify a callable template loader rather than a
``Loader`` class will be removed, as will the ``load_template_source``
functions that are included with the built in template loaders for
backwards compatibility.
* ``django.utils.translation.get_date_formats()`` and
``django.utils.translation.get_partial_date_formats()``. These functions
will be removed; use the locale-aware
``django.utils.formats.get_format()`` to get the appropriate formats.
* ``django.utils.translation.get_date_formats()`` and
``django.utils.translation.get_partial_date_formats()``. These functions
will be removed; use the locale-aware
``django.utils.formats.get_format()`` to get the appropriate formats.
* In ``django.forms.fields``, the constants: ``DEFAULT_DATE_INPUT_FORMATS``,
``DEFAULT_TIME_INPUT_FORMATS`` and
``DEFAULT_DATETIME_INPUT_FORMATS`` will be removed. Use
``django.utils.formats.get_format()`` to get the appropriate
formats.
* In ``django.forms.fields``, the constants: ``DEFAULT_DATE_INPUT_FORMATS``,
``DEFAULT_TIME_INPUT_FORMATS`` and
``DEFAULT_DATETIME_INPUT_FORMATS`` will be removed. Use
``django.utils.formats.get_format()`` to get the appropriate
formats.
* The ability to use a function-based test runners will be removed,
along with the ``django.test.simple.run_tests()`` test runner.
* The ability to use a function-based test runners will be removed,
along with the ``django.test.simple.run_tests()`` test runner.
* The ``views.feed()`` view and ``feeds.Feed`` class in
``django.contrib.syndication`` will be removed. The class-based view
``views.Feed`` should be used instead.
* The ``views.feed()`` view and ``feeds.Feed`` class in
``django.contrib.syndication`` will be removed. The class-based view
``views.Feed`` should be used instead.
* ``django.core.context_processors.auth``. This release will
remove the old method in favor of the new method in
``django.contrib.auth.context_processors.auth``.
* ``django.core.context_processors.auth``. This release will
remove the old method in favor of the new method in
``django.contrib.auth.context_processors.auth``.
* The ``postgresql`` database backend will be removed, use the
``postgresql_psycopg2`` backend instead.
* The ``postgresql`` database backend will be removed, use the
``postgresql_psycopg2`` backend instead.
* The ``no`` language code will be removed and has been replaced by the
``nb`` language code.
* The ``no`` language code will be removed and has been replaced by the
``nb`` language code.
* Authentication backends will need to define the boolean attribute
``supports_inactive_user`` until version 1.5 when it will be assumed that
all backends will handle inactive users.
* Authentication backends will need to define the boolean attribute
``supports_inactive_user`` until version 1.5 when it will be assumed that
all backends will handle inactive users.
* ``django.db.models.fields.XMLField`` will be removed. This was
deprecated as part of the 1.3 release. An accelerated deprecation
schedule has been used because the field hasn't performed any role
beyond that of a simple ``TextField`` since the removal of oldforms.
All uses of ``XMLField`` can be replaced with ``TextField``.
* ``django.db.models.fields.XMLField`` will be removed. This was
deprecated as part of the 1.3 release. An accelerated deprecation
schedule has been used because the field hasn't performed any role
beyond that of a simple ``TextField`` since the removal of oldforms.
All uses of ``XMLField`` can be replaced with ``TextField``.
1.5
@ -121,67 +121,67 @@ these changes.
See the :doc:`Django 1.3 release notes</releases/1.3>` for more details on
these changes.
* The ``mod_python`` request handler will be removed. The ``mod_wsgi``
handler should be used instead.
* The ``mod_python`` request handler will be removed. The ``mod_wsgi``
handler should be used instead.
* The ``template`` attribute on :class:`~django.test.client.Response`
objects returned by the :ref:`test client <test-client>` will be removed.
The :attr:`~django.test.client.Response.templates` attribute should be
used instead.
* The ``template`` attribute on :class:`~django.test.client.Response`
objects returned by the :ref:`test client <test-client>` will be removed.
The :attr:`~django.test.client.Response.templates` attribute should be
used instead.
* The :class:`~django.test.simple.DjangoTestRunner` will be removed.
Instead use a unittest-native class. The features of the
:class:`django.test.simple.DjangoTestRunner` (including fail-fast and
Ctrl-C test termination) can currently be provided by the unittest-native
:class:`TextTestRunner`.
* The :class:`~django.test.simple.DjangoTestRunner` will be removed.
Instead use a unittest-native class. The features of the
:class:`django.test.simple.DjangoTestRunner` (including fail-fast and
Ctrl-C test termination) can currently be provided by the unittest-native
:class:`TextTestRunner`.
* The undocumented function
:func:`django.contrib.formtools.utils.security_hash` will be removed,
instead use :func:`django.contrib.formtools.utils.form_hmac`
* The undocumented function
:func:`django.contrib.formtools.utils.security_hash` will be removed,
instead use :func:`django.contrib.formtools.utils.form_hmac`
* The function-based generic view modules will be removed in favor of their
class-based equivalents, outlined :doc:`here
</topics/generic-views-migration>`:
* The function-based generic view modules will be removed in favor of their
class-based equivalents, outlined :doc:`here
</topics/generic-views-migration>`:
* The :class:`~django.core.servers.basehttp.AdminMediaHandler` will be
removed. In its place use
:class:`~django.contrib.staticfiles.handlers.StaticFilesHandler`.
* The :class:`~django.core.servers.basehttp.AdminMediaHandler` will be
removed. In its place use
:class:`~django.contrib.staticfiles.handlers.StaticFilesHandler`.
* The :ttag:`url` and :ttag:`ssi` template tags will be
modified so that the first argument to each tag is a
template variable, not an implied string. Until then, the new-style
behavior is provided in the ``future`` template tag library.
* The :ttag:`url` and :ttag:`ssi` template tags will be
modified so that the first argument to each tag is a
template variable, not an implied string. Until then, the new-style
behavior is provided in the ``future`` template tag library.
* The :djadmin:`reset` and :djadmin:`sqlreset` management commands
will be removed.
* The :djadmin:`reset` and :djadmin:`sqlreset` management commands
will be removed.
* Authentication backends will need to support an inactive user
being passed to all methods dealing with permissions.
The ``supports_inactive_user`` attribute will no longer be checked
and can be removed from custom backends.
* Authentication backends will need to support an inactive user
being passed to all methods dealing with permissions.
The ``supports_inactive_user`` attribute will no longer be checked
and can be removed from custom backends.
* :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
a :class:`~django.contrib.gis.geos.GEOSException` when called
on a geometry with no SRID value.
* :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
a :class:`~django.contrib.gis.geos.GEOSException` when called
on a geometry with no SRID value.
* :class:`~django.http.CompatCookie` will be removed in favor of
:class:`~django.http.SimpleCookie`.
* :class:`~django.http.CompatCookie` will be removed in favor of
:class:`~django.http.SimpleCookie`.
* :class:`django.core.context_processors.PermWrapper` and
:class:`django.core.context_processors.PermLookupDict` will be removed in
favor of the corresponding
:class:`django.contrib.auth.context_processors.PermWrapper` and
:class:`django.contrib.auth.context_processors.PermLookupDict`,
respectively.
* :class:`django.core.context_processors.PermWrapper` and
:class:`django.core.context_processors.PermLookupDict` will be removed in
favor of the corresponding
:class:`django.contrib.auth.context_processors.PermWrapper` and
:class:`django.contrib.auth.context_processors.PermLookupDict`,
respectively.
* The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be
required to end with a trailing slash to ensure there is a consistent
way to combine paths in templates.
* The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be
required to end with a trailing slash to ensure there is a consistent
way to combine paths in templates.
* ``django.db.models.fields.URLField.verify_exists`` will be removed. The
feature was deprecated in 1.3.1 due to intractable security and
performance issues and will follow a slightly accelerated deprecation
timeframe.
* ``django.db.models.fields.URLField.verify_exists`` will be removed. The
feature was deprecated in 1.3.1 due to intractable security and
performance issues and will follow a slightly accelerated deprecation
timeframe.
1.6
---
@ -189,73 +189,73 @@ these changes.
See the :doc:`Django 1.4 release notes</releases/1.4>` for more details on
these changes.
* The compatibility modules ``django.utils.copycompat`` and
``django.utils.hashcompat`` as well as the functions
``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will
be removed. The Python builtin versions should be used instead.
* The compatibility modules ``django.utils.copycompat`` and
``django.utils.hashcompat`` as well as the functions
``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will
be removed. The Python builtin versions should be used instead.
* The :func:`~django.views.decorators.csrf.csrf_response_exempt` and
:func:`~django.views.decorators.csrf.csrf_view_exempt` decorators will
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
synonym for ``django.views.decorators.csrf.csrf_exempt``, which should
be used to replace it.
* The :func:`~django.views.decorators.csrf.csrf_response_exempt` and
:func:`~django.views.decorators.csrf.csrf_view_exempt` decorators will
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
synonym for ``django.views.decorators.csrf.csrf_exempt``, which should
be used to replace it.
* The :class:`~django.core.cache.backends.memcached.CacheClass` backend
was split into two in Django 1.3 in order to introduce support for
PyLibMC. The historical :class:`~django.core.cache.backends.memcached.CacheClass`
will be removed in favor of :class:`~django.core.cache.backends.memcached.MemcachedCache`.
* The :class:`~django.core.cache.backends.memcached.CacheClass` backend
was split into two in Django 1.3 in order to introduce support for
PyLibMC. The historical :class:`~django.core.cache.backends.memcached.CacheClass`
will be removed in favor of :class:`~django.core.cache.backends.memcached.MemcachedCache`.
* The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only
be accessible through their GB-prefixed names (GB is the correct
ISO 3166 code for United Kingdom).
* The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only
be accessible through their GB-prefixed names (GB is the correct
ISO 3166 code for United Kingdom).
* The :setting:`IGNORABLE_404_STARTS` and :setting:`IGNORABLE_404_ENDS`
settings have been superseded by :setting:`IGNORABLE_404_URLS` in
the 1.4 release. They will be removed.
* The :setting:`IGNORABLE_404_STARTS` and :setting:`IGNORABLE_404_ENDS`
settings have been superseded by :setting:`IGNORABLE_404_URLS` in
the 1.4 release. They will be removed.
* The :doc:`form wizard </ref/contrib/formtools/form-wizard>` has been
refactored to use class based views with pluggable backends in 1.4.
The previous implementation will be removed.
* The :doc:`form wizard </ref/contrib/formtools/form-wizard>` has been
refactored to use class based views with pluggable backends in 1.4.
The previous implementation will be removed.
* Legacy ways of calling
:func:`~django.views.decorators.cache.cache_page` will be removed.
* Legacy ways of calling
:func:`~django.views.decorators.cache.cache_page` will be removed.
* The backward-compatibility shim to automatically add a debug-false
filter to the ``'mail_admins'`` logging handler will be removed. The
:setting:`LOGGING` setting should include this filter explicitly if
it is desired.
* The backward-compatibility shim to automatically add a debug-false
filter to the ``'mail_admins'`` logging handler will be removed. The
:setting:`LOGGING` setting should include this filter explicitly if
it is desired.
* The template tag
:func:`django.contrib.admin.templatetags.adminmedia.admin_media_prefix`
will be removed in favor of the generic static files handling.
* The template tag
:func:`django.contrib.admin.templatetags.adminmedia.admin_media_prefix`
will be removed in favor of the generic static files handling.
* The builtin truncation functions :func:`django.utils.text.truncate_words`
and :func:`django.utils.text.truncate_html_words` will be removed in
favor of the ``django.utils.text.Truncator`` class.
* The builtin truncation functions :func:`django.utils.text.truncate_words`
and :func:`django.utils.text.truncate_html_words` will be removed in
favor of the ``django.utils.text.Truncator`` class.
* 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.utils` will be removed.
* 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.utils` will be removed.
* ``django.conf.urls.defaults`` will be removed. The functions
:func:`~django.conf.urls.include`, :func:`~django.conf.urls.patterns` and
:func:`~django.conf.urls.url` plus :data:`~django.conf.urls.handler404`,
:data:`~django.conf.urls.handler500`, are now available through
:mod:`django.conf.urls` .
* ``django.conf.urls.defaults`` will be removed. The functions
:func:`~django.conf.urls.include`, :func:`~django.conf.urls.patterns` and
:func:`~django.conf.urls.url` plus :data:`~django.conf.urls.handler404`,
:data:`~django.conf.urls.handler500`, are now available through
: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
:func:`~django.core.management.execute_manager` will be removed from
:mod:`django.core.management`. This also means that the old (pre-1.4)
style of :file:`manage.py` file will no longer work.
* The functions :func:`~django.core.management.setup_environ` and
:func:`~django.core.management.execute_manager` will be removed from
:mod:`django.core.management`. This also means that the old (pre-1.4)
style of :file:`manage.py` file will no longer work.
2.0
---
* ``django.views.defaults.shortcut()``. This function has been moved
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
goal of removing all ``django.contrib`` references from the core
Django codebase. The old shortcut will be removed in the 2.0
release.
* ``django.views.defaults.shortcut()``. This function has been moved
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
goal of removing all ``django.contrib`` references from the core
Django codebase. The old shortcut will be removed in the 2.0
release.

View File

@ -9,27 +9,27 @@ Official releases
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
changes to Django, and these changes are not necessarily
backwards-compatible. That is, code you wrote for Django 1.2 may break
when we release Django 2.0.
* ``A`` is the *major version* number, which is only incremented for major
changes to Django, and these changes are not necessarily
backwards-compatible. That is, code you wrote for Django 1.2 may break
when we release Django 2.0.
* ``B`` is the *minor version* number, which is incremented for large yet
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
release notes.
* ``B`` is the *minor version* number, which is incremented for large yet
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
release notes.
* ``C`` is the *micro version* number, which is incremented for bug and
security fixes. A new micro-release will be 100% backwards-compatible with
the previous micro-release. The only exception is when a security issue
can't be fixed without breaking backwards-compatibility. If this happens,
the release notes will provide detailed upgrade instructions.
* ``C`` is the *micro version* number, which is incremented for bug and
security fixes. A new micro-release will be 100% backwards-compatible with
the previous micro-release. The only exception is when a security issue
can't be fixed without breaking backwards-compatibility. If this happens,
the release notes will provide detailed upgrade instructions.
* 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``
alpha/beta/release candidate of version ``A.B``.
* 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``
alpha/beta/release candidate of version ``A.B``.
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
@ -59,15 +59,15 @@ remove the feature entirely.
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
which will raise a ``PendingDeprecationWarning``. This warning is silent
by default; you need to explicitly turn on display of these warnings.
* Django 1.1 will contain a backwards-compatible replica of the function
which will raise a ``PendingDeprecationWarning``. This warning is silent
by default; you need to explicitly turn on display of these warnings.
* Django 1.2 will contain the backwards-compatible replica, but the warning
will be promoted to a full-fledged ``DeprecationWarning``. This warning is
*loud* by default, and will likely be quite annoying.
* Django 1.2 will contain the backwards-compatible replica, but the warning
will be promoted to a full-fledged ``DeprecationWarning``. This warning is
*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
--------------
@ -90,38 +90,38 @@ Supported versions
At any moment in time, Django's developer team will support a set of releases to
varying levels:
* The current development trunk will get new features and bug fixes
requiring major refactoring.
* The current development trunk will get new features and bug fixes
requiring major refactoring.
* 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
problems:
* 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
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
release for bugs that would have prevented a release in the first place.
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.
* Security fixes will be applied to the current trunk and the previous two
minor releases.
* Security fixes will be applied to the current trunk and the previous two
minor releases.
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:
* 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
1.3.1, 1.3.2, etc.
* Critical bug fixes will be applied to a ``1.3.X`` branch, and released as
1.3.1, 1.3.2, etc.
* 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``,
etc.
* 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``,
etc.
.. _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,
development will be happening in a bunch of places:
* On trunk, development towards 1.2 proceeds with small additions, bugs
fixes, etc. being checked in daily.
* On trunk, development towards 1.2 proceeds with small additions, bugs
fixes, etc. being checked in daily.
* 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
be released as "1.1.1", "1.1.2", etc.
* 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
be released as "1.1.1", "1.1.2", etc.
* On the branch "branches/releases/1.0.X", security fixes are made if
needed and released as "1.0.2", "1.0.3", etc.
* On the branch "branches/releases/1.0.X", security fixes are made if
needed and released as "1.0.2", "1.0.3", etc.
* On feature branches, development of major features is done. These
branches will be merged into trunk before the end of phase two.
* On feature branches, development of major features is done. These
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:
* Install a version of Django :doc:`provided by your operating system
distribution </misc/distributions>`. This is the quickest option for those
who have operating systems that distribute Django.
* Install a version of Django :doc:`provided by your operating system
distribution </misc/distributions>`. This is the quickest option for those
who have operating systems that distribute Django.
* :ref:`Install an official release <installing-official-release>`. This
is the best approach for users who want a stable version number and aren't
concerned about running a slightly older version of Django.
* :ref:`Install an official release <installing-official-release>`. This
is the best approach for users who want a stable version number and aren't
concerned about running a slightly older version of Django.
* :ref:`Install the latest development version
<installing-development-version>`. This is best for users who want the
latest-and-greatest features and aren't afraid of running brand-new code.
* :ref:`Install the latest development version
<installing-development-version>`. This is best for users who want the
latest-and-greatest features and aren't afraid of running brand-new code.
.. admonition:: Always refer to the documentation that corresponds to the
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
features:
* A :doc:`caching framework </topics/cache>` that integrates with memcached
or other backends.
* A :doc:`caching framework </topics/cache>` that integrates with memcached
or other backends.
* A :doc:`syndication framework </ref/contrib/syndication>` that makes
creating RSS and Atom feeds as easy as writing a small Python class.
* A :doc:`syndication framework </ref/contrib/syndication>` that makes
creating RSS and Atom feeds as easy as writing a small Python class.
* More sexy automatically-generated admin features -- this overview barely
scratched the surface.
* More sexy automatically-generated admin features -- this overview barely
scratched the surface.
The next obvious steps are for you to `download Django`_, read :doc:`the
tutorial </intro/tutorial01>` and join `the community`_. Thanks for your

View File

@ -9,8 +9,8 @@ poll application.
It'll consist of two parts:
* A public site that lets people view polls and vote in them.
* An admin site that lets you add, change and delete polls.
* A public site that lets people view polls and vote in them.
* An admin site that lets you add, change and delete polls.
We'll assume you have :doc:`Django installed </intro/install>` already. You can
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
your databases connection settings.
* :setting:`ENGINE <DATABASE-ENGINE>` -- Either
``'django.db.backends.postgresql_psycopg2'``,
``'django.db.backends.mysql'`` or
``'django.db.backends.sqlite3'``. Other backends are
:setting:`also available <DATABASE-ENGINE>`.
* :setting:`ENGINE <DATABASE-ENGINE>` -- Either
``'django.db.backends.postgresql_psycopg2'``,
``'django.db.backends.mysql'`` or
``'django.db.backends.sqlite3'``. Other backends are
:setting:`also available <DATABASE-ENGINE>`.
* :setting:`NAME` -- The name of your database. If you're using
SQLite, the database will be a file on your computer; in that
case, :setting:`NAME` should be the full absolute path,
including filename, of that file. If the file doesn't exist, it
will automatically be created when you synchronize the database
for the first time (see below).
* :setting:`NAME` -- The name of your database. If you're using
SQLite, the database will be a file on your computer; in that
case, :setting:`NAME` should be the full absolute path,
including filename, of that file. If the file doesn't exist, it
will automatically be created when you synchronize the database
for the first time (see below).
When specifying the path, always use forward slashes, even on
Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
When specifying the path, always use forward slashes, even on
Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
* :setting:`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
SQLite).
* :setting:`PASSWORD` -- Your database password (not used for
SQLite).
* :setting:`HOST` -- The host your database is on. Leave this as
an empty string if your database server is on the same physical
machine (not used for SQLite).
* :setting:`HOST` -- The host your database is on. Leave this as
an empty string if your database server is on the same physical
machine (not used for SQLite).
If you're new to databases, we recommend simply using SQLite (by
setting :setting:`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
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
with one Django installation.
* :mod:`django.contrib.sites` -- A framework for managing multiple sites
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
static files.
* :mod:`django.contrib.staticfiles` -- A framework for managing
static files.
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
is able to:
* Create a database schema (``CREATE TABLE`` statements) for this app.
* Create a Python database-access API for accessing Poll and Choice objects.
* Create a database schema (``CREATE TABLE`` statements) for this app.
* 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.
@ -441,52 +441,52 @@ statements for the polls app):
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
(``polls``) and the lowercase name of the model -- ``poll`` and
``choice``. (You can override this behavior.)
* Table names are automatically generated by combining the name of the app
(``polls``) and the lowercase name of the model -- ``poll`` and
``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.
Yes, you can override this, as well.
* By convention, Django appends ``"_id"`` to the foreign key field name.
Yes, you can override this, as well.
* The foreign key relationship is made explicit by a ``REFERENCES``
statement.
* The foreign key relationship is made explicit by a ``REFERENCES``
statement.
* It's tailored to the database you're using, so database-specific field
types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
``integer primary key`` (SQLite) are handled for you automatically. Same
goes for quoting of field names -- e.g., using double quotes or single
quotes. The author of this tutorial runs PostgreSQL, so the example
output is in PostgreSQL syntax.
* It's tailored to the database you're using, so database-specific field
types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
``integer primary key`` (SQLite) are handled for you automatically. Same
goes for quoting of field names -- e.g., using double quotes or single
quotes. The author of this tutorial runs PostgreSQL, so the example
output is in PostgreSQL syntax.
* 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
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
easier way of committing the SQL to the 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
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
easier way of committing the SQL to the database.
If you're interested, also run the following commands:
* :djadmin:`python manage.py validate <validate>` -- Checks for any errors
in the construction of your models.
* :djadmin:`python manage.py validate <validate>` -- Checks for any errors
in the construction of your models.
* :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any
:ref:`custom SQL statements <initial-sql>` (such as table modifications or
constraints) that are defined for the application.
* :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any
:ref:`custom SQL statements <initial-sql>` (such as table modifications or
constraints) that are defined for the application.
* :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the
necessary ``DROP TABLE`` statements for this app, according to which
tables already exist in your database (if any).
* :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the
necessary ``DROP TABLE`` statements for this app, according to which
tables already exist in your database (if any).
* :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the
``CREATE INDEX`` statements for this app.
* :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the
``CREATE INDEX`` statements for this app.
* :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all
the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and
:djadmin:`sqlindexes` commands.
* :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all
the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and
:djadmin:`sqlindexes` commands.
Looking at the output of those commands can help you understand what's actually
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
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
to :setting:`INSTALLED_APPS`, the database tables need to be updated.
* Run ``python manage.py syncdb``. Since you have added a new application
to :setting:`INSTALLED_APPS`, the database tables need to be updated.
* 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
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
should have a ``urls.py`` file that looks like this:
* 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
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
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:
**from django.contrib import admin**
**admin.autodiscover()**
# Uncomment the next two lines to enable the admin:
**from django.contrib import admin**
**admin.autodiscover()**
urlpatterns = patterns('',
# Examples:
# url(r'^$', '{{ project_name }}.views.home', name='home'),
# url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
urlpatterns = patterns('',
# Examples:
# url(r'^$', '{{ project_name }}.views.home', name='home'),
# url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
**url(r'^admin/', include(admin.site.urls)),**
)
# Uncomment the next line to enable the admin:
**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
============================
@ -145,29 +145,29 @@ Click the "What's up?" poll to edit it:
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`,
:class:`~django.db.models.CharField`) correspond to the appropriate HTML
input widget. Each type of field knows how to display itself in the Django
admin.
* The different model field types (:class:`~django.db.models.DateTimeField`,
:class:`~django.db.models.CharField`) correspond to the appropriate HTML
input widget. Each type of field knows how to display itself in the Django
admin.
* Each :class:`~django.db.models.DateTimeField` gets free JavaScript
shortcuts. Dates get a "Today" shortcut and calendar popup, and times get
a "Now" shortcut and a convenient popup that lists commonly entered times.
* Each :class:`~django.db.models.DateTimeField` gets free JavaScript
shortcuts. Dates get a "Today" shortcut and calendar popup, and times get
a "Now" shortcut and a convenient popup that lists commonly entered times.
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
object.
* Save -- Saves changes and returns to the change-list page for this type of
object.
* Save and continue editing -- Saves changes and reloads the admin page for
this object.
* Save and continue editing -- Saves changes and reloads the admin page for
this object.
* Save and add another -- Saves changes and loads a new, blank form for this
type of object.
* Save and add another -- Saves changes and loads a new, blank form for this
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
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
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
given year.
* Year-based archive page -- displays all months with entries in the
given year.
* Month-based archive page -- displays all days with entries in the
given month.
* Month-based archive page -- displays all days with entries in the
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:
* 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
with a form to vote.
* Poll "detail" page -- displays a poll question, with no results but
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
poll.
* Vote action -- handles voting for a particular choice in a particular
poll.
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:
* 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
be rendered) because the traceback will be displayed instead.
* 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
be rendered) because the traceback will be displayed instead.
* The 404 view is also called if Django doesn't find a match after checking
every regular expression in the URLconf.
* The 404 view is also called if Django doesn't find a match after checking
every regular expression in the URLconf.
* 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``
template in the root of your template directory. The default 404 view will
use that template for all 404 errors.
* 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``
template in the root of your template directory. The default 404 view will
use that template for all 404 errors.
* 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.
So remember to create a ``404.html``.
* 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.
So remember to create a ``404.html``.
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:
* 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
remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
further processing.
* Then, Django will strip off the matching text (``"polls/"``) and send the
remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
further processing.
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

View File

@ -29,28 +29,28 @@ tutorial, so that the template contains an HTML ``<form>`` element:
A quick rundown:
* 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
``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
POST data ``choice=3``. This is HTML Forms 101.
* 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
``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
POST data ``choice=3``. This is HTML Forms 101.
* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
set ``method="post"``. Using ``method="post"`` (as opposed to
``method="get"``) is very important, because the act of submitting this
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
Django; it's just good Web development practice.
* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
set ``method="post"``. Using ``method="post"`` (as opposed to
``method="get"``) is very important, because the act of submitting this
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
Django; it's just good Web development practice.
* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
through its loop
* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
through its loop
* Since we're creating a POST form (which can have the effect of modifying
data), we need to worry about Cross Site Request Forgeries.
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
forms that are targeted at internal URLs should use the
:ttag:`{% csrf_token %}<csrf_token>` template tag.
* Since we're creating a POST form (which can have the effect of modifying
data), we need to worry about Cross Site Request Forgeries.
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
forms that are targeted at internal URLs should use the
:ttag:`{% csrf_token %}<csrf_token>` template tag.
The :ttag:`{% csrf_token %}<csrf_token>` tag requires information from the
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:
* :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like
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
string. :attr:`request.POST <django.http.HttpRequest.POST>` values are
always strings.
* :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like
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
string. :attr:`request.POST <django.http.HttpRequest.POST>` values are
always strings.
Note that Django also provides :attr:`request.GET
<django.http.HttpRequest.GET>` for accessing GET data in the same way --
but we're explicitly using :attr:`request.POST
<django.http.HttpRequest.POST>` in our code, to ensure that data is only
altered via a POST call.
Note that Django also provides :attr:`request.GET
<django.http.HttpRequest.GET>` for accessing GET data in the same way --
but we're explicitly using :attr:`request.POST
<django.http.HttpRequest.POST>` in our code, to ensure that data is only
altered via a POST call.
* ``request.POST['choice']`` will raise :exc:`KeyError` if ``choice`` wasn't
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.
* ``request.POST['choice']`` will raise :exc:`KeyError` if ``choice`` wasn't
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.
* After incrementing the choice count, the code returns an
:class:`~django.http.HttpResponseRedirect` rather than a normal
:class:`~django.http.HttpResponse`.
:class:`~django.http.HttpResponseRedirect` takes a single argument: the
URL to which the user will be redirected (see the following point for how
we construct the URL in this case).
* After incrementing the choice count, the code returns an
:class:`~django.http.HttpResponseRedirect` rather than a normal
:class:`~django.http.HttpResponse`.
:class:`~django.http.HttpResponseRedirect` takes a single argument: the
URL to which the user will be redirected (see the following point for how
we construct the URL in this case).
As the Python comment above points out, you should always return an
:class:`~django.http.HttpResponseRedirect` after successfully dealing with
POST data. This tip isn't specific to Django; it's just good Web
development practice.
As the Python comment above points out, you should always return an
:class:`~django.http.HttpResponseRedirect` after successfully dealing with
POST data. This tip isn't specific to Django; it's just good Web
development practice.
* We are using the :func:`~django.core.urlresolvers.reverse` function in the
:class:`~django.http.HttpResponseRedirect` constructor in this example.
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
variable portion of the URL pattern that points to that view. In this
case, using the URLconf we set up in Tutorial 3, this
:func:`~django.core.urlresolvers.reverse` call will return a string like
::
* We are using the :func:`~django.core.urlresolvers.reverse` function in the
:class:`~django.http.HttpResponseRedirect` constructor in this example.
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
variable portion of the URL pattern that points to that view. In this
case, using the URLconf we set up in Tutorial 3, this
: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
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).
... 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
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`
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
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.
@ -257,22 +257,22 @@ We're using two generic views here:
two views abstract the concepts of "display a list of objects" and
"display a detail page for a particular type of object."
* Each generic view needs to know what model it will be acting
upon. This is provided using the ``model`` parameter.
* Each generic view needs to know what model it will be acting
upon. This is provided using the ``model`` parameter.
* The :class:`~django.views.generic.list.DetailView` generic view
expects the primary key value captured from the URL to be called
``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic
views.
* The :class:`~django.views.generic.list.DetailView` generic view
expects the primary key value captured from the URL to be called
``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic
views.
* 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
documentation about :ref:`naming URL patterns
<naming-url-patterns>` for information). We're also using the
:func:`~django.conf.urls.url` function from
:mod:`django.conf.urls` here. It's a good habit to use
:func:`~django.conf.urls.url` when you are providing a
pattern name like this.
* 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
documentation about :ref:`naming URL patterns
<naming-url-patterns>` for information). We're also using the
:func:`~django.conf.urls.url` function from
:mod:`django.conf.urls` here. It's a good habit to use
:func:`~django.conf.urls.url` when you are providing a
pattern name like this.
By default, the :class:`~django.views.generic.list.DetailView` generic
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
will cover:
* Advanced form processing
* Using the RSS framework
* Using the cache framework
* Using the comments framework
* Advanced admin features: Permissions
* Advanced admin features: Custom JavaScript
* Advanced form processing
* Using the RSS framework
* Using the cache framework
* Using the comments framework
* Advanced admin features: Permissions
* Advanced admin features: Custom JavaScript
In the meantime, you might want to check out some pointers on :doc:`where to go
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
different needs:
* The :doc:`introductory material </intro/index>` is designed for people new
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
Django "feels".
* The :doc:`introductory material </intro/index>` is designed for people new
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
Django "feels".
* The :doc:`topic guides </topics/index>`, on the other hand, dive deep into
individual parts of Django. There are complete guides to Django's
:doc:`model system </topics/db/index>`, :doc:`template engine
</topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much
more.
* The :doc:`topic guides </topics/index>`, on the other hand, dive deep into
individual parts of Django. There are complete guides to Django's
:doc:`model system </topics/db/index>`, :doc:`template engine
</topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much
more.
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
everything there is to know about Django.
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
everything there is to know about Django.
* 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
common "How do I ...?" questions. Here you'll find information about
:doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing
custom template tags </howto/custom-template-tags>`, and more.
* 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
common "How do I ...?" questions. Here you'll find information about
:doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing
custom template tags </howto/custom-template-tags>`, and more.
Answers to really common questions can also be found in the :doc:`FAQ
</faq/index>`.
Answers to really common questions can also be found in the :doc:`FAQ
</faq/index>`.
* 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
trying to learn. Instead, details about individual classes, functions,
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
whathaveyou.
* 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
trying to learn. Instead, details about individual classes, functions,
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
whathaveyou.
* Finally, there's some "specialized" documentation not usually relevant to
most developers. This includes the :doc:`release notes </releases/index>`,
:doc:`documentation of obsolete features </obsolete/index>`,
: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
elsewhere </misc/index>`.
* Finally, there's some "specialized" documentation not usually relevant to
most developers. This includes the :doc:`release notes </releases/index>`,
:doc:`documentation of obsolete features </obsolete/index>`,
: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
elsewhere </misc/index>`.
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
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
expanded.
* To add information and/or examples to existing sections that need to be
expanded.
* To document Django features that aren't yet documented. (The list of
such features is shrinking but exists nonetheless.)
* To document Django features that aren't yet documented. (The list of
such features is shrinking but exists nonetheless.)
* To add documentation for new features as new features get added, or as
Django APIs or behaviors change.
* To add documentation for new features as new features get added, or as
Django APIs or behaviors change.
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
@ -164,33 +164,33 @@ As HTML, locally
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
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
``easy_install``:
* Django's documentation uses a system called Sphinx__ to convert from
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
``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
HTML:
* Then, just use the included ``Makefile`` to turn the documentation into
HTML:
.. code-block:: bash
.. code-block:: bash
$ cd path/to/django/docs
$ make html
$ cd path/to/django/docs
$ 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
make.bat html
cd path\to\django\docs
make.bat html
* The HTML documentation will be placed in ``docs/_build/html``.
* The HTML documentation will be placed in ``docs/_build/html``.
.. note::
@ -212,27 +212,27 @@ versions of the framework.
We follow this policy:
* The primary documentation on djangoproject.com is an HTML version of the
latest docs in Subversion. These docs always correspond to the latest
official Django release, plus whatever features we've added/changed in
the framework *since* the latest release.
* The primary documentation on djangoproject.com is an HTML version of the
latest docs in Subversion. These docs always correspond to the latest
official Django release, plus whatever features we've added/changed in
the framework *since* the latest release.
* As we add features to Django's development version, we try to update the
documentation in the same Subversion commit transaction.
* As we add features to Django's development version, we try to update the
documentation in the same Subversion commit transaction.
* 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
being developed).
* 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
being developed).
* 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
moment of the release. We will make exceptions to this rule in
the case of retroactive security updates or other such retroactive
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"
and links to the current version of that document.
* 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
moment of the release. We will make exceptions to this rule in
the case of retroactive security updates or other such retroactive
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"
and links to the current version of that document.
* The `main documentation Web page`_ includes links to documentation for
all previous versions.
* The `main documentation Web page`_ includes links to documentation for
all previous versions.
.. _main documentation Web page: http://docs.djangoproject.com/en/dev/

View File

@ -12,24 +12,24 @@ What "stable" means
In this context, stable means:
- 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
renamed without providing backwards-compatible aliases.
- 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
renamed without providing backwards-compatible aliases.
- 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
words, "stable" does not (necessarily) mean "complete."
- 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
words, "stable" does not (necessarily) mean "complete."
- 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
minor version releases. Warnings will be issued when the deprecated method
is called.
- 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
minor version releases. Warnings will be issued when the deprecated method
is called.
See :ref:`official-releases` for more details on how Django's version
numbering scheme works, and how features will be deprecated.
See :ref:`official-releases` for more details on how Django's version
numbering scheme works, and how features will be deprecated.
- We'll only break backwards compatibility of these APIs if a bug or
security hole makes it completely unavoidable.
- We'll only break backwards compatibility of these APIs if a bug or
security hole makes it completely unavoidable.
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
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
</topics/db/index>`
- :doc:`Model definition, managers, querying and transactions
</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
uploads, middleware, sessions, URL resolution, view, and shortcut APIs.
- :doc:`HTTP request/response handling </topics/http/index>`, including file
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:`template APIs </ref/templates/index>`, and :doc:`custom template tags
and libraries </howto/custom-template-tags>`. We may add new template
tags in the future and the names may inadvertently clash with
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.
- :doc:`Templates </topics/templates>`, including the language, Python-level
:doc:`template APIs </ref/templates/index>`, and :doc:`custom template tags
and libraries </howto/custom-template-tags>`. We may add new template
tags in the future and the names may inadvertently clash with
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.
- :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
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
places where "'stable' does not mean 'complete.'"
- :doc:`Settings </ref/settings>`. Note, though that while the :doc:`list of
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
places where "'stable' does not mean 'complete.'"
- :doc:`Built-in signals </ref/signals>`. Like settings, we'll probably add
new signals in the future, but the existing ones won't break.
- :doc:`Built-in signals </ref/signals>`. Like settings, we'll probably add
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``
----------------
@ -97,15 +97,15 @@ of 1.0. This includes these APIs:
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:
- ``django.utils.cache``
- ``django.utils.datastructures.SortedDict`` -- only this single class; the
rest of the module is for internal use.
- ``django.utils.encoding``
- ``django.utils.feedgenerator``
- ``django.utils.http``
- ``django.utils.safestring``
- ``django.utils.translation``
- ``django.utils.tzinfo``
- ``django.utils.cache``
- ``django.utils.datastructures.SortedDict`` -- only this single class; the
rest of the module is for internal use.
- ``django.utils.encoding``
- ``django.utils.feedgenerator``
- ``django.utils.http``
- ``django.utils.safestring``
- ``django.utils.translation``
- ``django.utils.tzinfo``
Exceptions
==========
@ -142,13 +142,13 @@ APIs marked as internal
Certain APIs are explicitly marked as "internal" in a couple of ways:
- Some documentation refers to internals and mentions them as such. If the
documentation says that something is internal, we reserve the right to
change it.
- Some documentation refers to internals and mentions them as such. If the
documentation says that something is internal, we reserve the right to
change it.
- Functions, methods, and other objects prefixed by a leading underscore
(``_``). This is the standard Python way of indicating that something is
private; if any method starts with a single ``_``, it's an internal API.
- Functions, methods, and other objects prefixed by a leading underscore
(``_``). This is the standard Python way of indicating that something is
private; if any method starts with a single ``_``, it's an internal API.
.. _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
local flavor:
* At the time of a Django release, the data and algorithms
contained in :mod:`django.contrib.localflavor` will, to the best
of our ability, reflect the officially gazetted policies of the
appropriate local government authority. If a province has been
added, altered, or removed, that change will be reflected in
Django's localflavor.
* At the time of a Django release, the data and algorithms
contained in :mod:`django.contrib.localflavor` will, to the best
of our ability, reflect the officially gazetted policies of the
appropriate local government authority. If a province has been
added, altered, or removed, that change will be reflected in
Django's localflavor.
* These changes will *not* be backported to the previous stable
release. Upgrading a minor version of Django should not require
any data migration or audits for UI changes; therefore, if you
want to get the latest province list, you will either need to
upgrade your Django install, or backport the province list you
need.
* These changes will *not* be backported to the previous stable
release. Upgrading a minor version of Django should not require
any data migration or audits for UI changes; therefore, if you
want to get the latest province list, you will either need to
upgrade your Django install, or backport the province list you
need.
* For one release, the affected localflavor module will raise a
``RuntimeWarning`` when it is imported.
* For one release, the affected localflavor module will raise a
``RuntimeWarning`` when it is imported.
* The change will be announced in the release notes as a backwards
incompatible change requiring attention. The change will also be
annotated in the documentation for the localflavor module.
* The change will be announced in the release notes as a backwards
incompatible change requiring attention. The change will also be
annotated in the documentation for the localflavor module.
* Where necessary and feasible, a migration script will be provided
to aid the migration process.
* Where necessary and feasible, a migration script will be provided
to aid the migration process.
For example, Django 1.2 contains an Indonesian localflavor. It has 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:
* Assignment to variables
* Advanced logic
* Assignment to variables
* Advanced logic
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

View File

@ -41,13 +41,13 @@ usable generic views.
For example, the :class:`~django.views.generic.base.detail.DetailView`
is composed from:
* :class:`~django.db.views.generic.base.View`, which provides the
basic class-based behavior
* :class:`~django.db.views.generic.detail.SingleObjectMixin`, which
provides the utilities for retrieving and displaying a single object
* :class:`~django.db.views.generic.detail.SingleObjectTemplateResponseMixin`,
which provides the tools for rendering a single object into a
template-based response.
* :class:`~django.db.views.generic.base.View`, which provides the
basic class-based behavior
* :class:`~django.db.views.generic.detail.SingleObjectMixin`, which
provides the utilities for retrieving and displaying a single object
* :class:`~django.db.views.generic.detail.SingleObjectTemplateResponseMixin`,
which provides the tools for rendering a single object into a
template-based response.
When combined, these mixins provide all the pieces necessary to
provide a view over a single object that renders a template to produce
@ -192,9 +192,9 @@ SingleObjectMixin
**Context**
* ``object``: The object that this view is displaying. If
``context_object_name`` is specified, that variable will also be
set in the context, with the same value as ``object``.
* ``object``: The object that this view is displaying. If
``context_object_name`` is specified, that variable will also be
set in the context, with the same value as ``object``.
SingleObjectTemplateResponseMixin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -210,7 +210,7 @@ SingleObjectTemplateResponseMixin
**Extends**
* :class:`~django.views.generic.base.TemplateResponseMixin`
* :class:`~django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name_field
@ -229,10 +229,10 @@ SingleObjectTemplateResponseMixin
Returns a list of candidate template names. Returns the following list:
* the value of ``template_name`` on the view (if provided)
* the contents of the ``template_name_field`` field on the
object instance that the view is operating upon (if available)
* ``<app_label>/<object_name><template_name_suffix>.html``
* the value of ``template_name`` on the view (if provided)
* the contents of the ``template_name_field`` field on the
object instance that the view is operating upon (if available)
* ``<app_label>/<object_name><template_name_suffix>.html``
Multiple object mixins
----------------------
@ -248,15 +248,15 @@ MultipleObjectMixin
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:
* Use the ``page`` parameter in the URLconf. For example, this is what
your URLconf might look like::
* Use the ``page`` parameter in the URLconf. For example, this is what
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
example, a URL would look like this::
* Pass the page number via the ``page`` query-string parameter. For
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
represented as page ``1``.
@ -363,22 +363,22 @@ MultipleObjectMixin
**Context**
* ``object_list``: The list of objects that this view is displaying. If
``context_object_name`` is specified, that variable will also be set
in the context, with the same value as ``object_list``.
* ``object_list``: The list of objects that this view is displaying. If
``context_object_name`` is specified, that variable will also be set
in the context, with the same value as ``object_list``.
* ``is_paginated``: A boolean representing whether the results are
paginated. Specifically, this is set to ``False`` if no page size has
been specified, or if the available objects do not span multiple
pages.
* ``is_paginated``: A boolean representing whether the results are
paginated. Specifically, this is set to ``False`` if no page size has
been specified, or if the available objects do not span multiple
pages.
* ``paginator``: An instance of
:class:`django.core.paginator.Paginator`. If the page is not
paginated, this context variable will be ``None``.
* ``paginator``: An instance of
:class:`django.core.paginator.Paginator`. If the page is not
paginated, this context variable will be ``None``.
* ``page_obj``: An instance of
:class:`django.core.paginator.Page`. If the page is not paginated,
this context variable will be ``None``.
* ``page_obj``: An instance of
:class:`django.core.paginator.Page`. If the page is not paginated,
this context variable will be ``None``.
MultipleObjectTemplateResponseMixin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -392,7 +392,7 @@ MultipleObjectTemplateResponseMixin
**Extends**
* :class:`~django.views.generic.base.TemplateResponseMixin`
* :class:`~django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name_suffix
@ -403,8 +403,8 @@ MultipleObjectTemplateResponseMixin
Returns a list of candidate template names. Returns the following list:
* the value of ``template_name`` on the view (if provided)
* ``<app_label>/<object_name><template_name_suffix>.html``
* the value of ``template_name`` on the view (if provided)
* ``<app_label>/<object_name><template_name_suffix>.html``
Editing mixins
--------------
@ -471,7 +471,7 @@ FormMixin
**Context**
* ``form``: The form instance that was generated for the view.
* ``form``: The form instance that was generated for the view.
.. note::
@ -495,8 +495,8 @@ ModelFormMixin
**Mixins**
* :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.detail.SingleObjectMixin`
* :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.detail.SingleObjectMixin`
.. attribute:: success_url
@ -604,9 +604,9 @@ YearMixin
Returns the year for which this view will display data. Tries the
following sources, in order:
* The value of the :attr:`YearMixin.year` attribute.
* The value of the `year` argument captured in the URL pattern
* The value of the `year` GET query argument.
* The value of the :attr:`YearMixin.year` attribute.
* The value of the `year` argument captured in the URL pattern
* The value of the `year` GET query argument.
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
following sources, in order:
* The value of the :attr:`MonthMixin.month` attribute.
* The value of the `month` argument captured in the URL pattern
* The value of the `month` GET query argument.
* The value of the :attr:`MonthMixin.month` attribute.
* The value of the `month` argument captured in the URL pattern
* The value of the `month` GET query argument.
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
following sources, in order:
* The value of the :attr:`DayMixin.day` attribute.
* The value of the `day` argument captured in the URL pattern
* The value of the `day` GET query argument.
* The value of the :attr:`DayMixin.day` attribute.
* The value of the `day` argument captured in the URL pattern
* The value of the `day` GET query argument.
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
following sources, in order:
* The value of the :attr:`WeekMixin.week` attribute.
* The value of the `week` argument captured in the URL pattern
* The value of the `week` GET query argument.
* The value of the :attr:`WeekMixin.week` attribute.
* The value of the `week` argument captured in the URL pattern
* The value of the `week` GET query argument.
Raises a 404 if no valid week specification can be found.
@ -782,8 +782,8 @@ BaseDateListView
**Mixins**
* :class:`~django.views.generic.dates.DateMixin`
* :class:`~django.views.generic.list.MultipleObjectMixin`
* :class:`~django.views.generic.dates.DateMixin`
* :class:`~django.views.generic.list.MultipleObjectMixin`
.. attribute:: allow_empty
@ -888,7 +888,7 @@ TemplateView
**Mixins**
* :class:`django.views.generic.base.TemplateResponseMixin`
* :class:`django.views.generic.base.TemplateResponseMixin`
.. attribute:: template_name
@ -901,8 +901,8 @@ TemplateView
**Context**
* ``params``: The dictionary of keyword arguments captured from the URL
pattern that served the view.
* ``params``: The dictionary of keyword arguments captured from the URL
pattern that served the view.
RedirectView
~~~~~~~~~~~~
@ -971,8 +971,8 @@ DetailView
**Mixins**
* :class:`django.views.generic.detail.SingleObjectMixin`
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
* :class:`django.views.generic.detail.SingleObjectMixin`
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
List views
----------
@ -997,8 +997,8 @@ ListView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectMixin`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.list.MultipleObjectMixin`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
Editing views
@ -1020,8 +1020,8 @@ FormView
**Mixins**
* :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
* :class:`django.views.generic.edit.FormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
CreateView
~~~~~~~~~~
@ -1037,8 +1037,8 @@ CreateView
**Mixins**
* :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
* :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
UpdateView
~~~~~~~~~~
@ -1056,8 +1056,8 @@ UpdateView
**Mixins**
* :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
* :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
DeleteView
~~~~~~~~~~
@ -1075,13 +1075,13 @@ DeleteView
**Mixins**
* :class:`django.views.generic.edit.DeletionMixin`
* :class:`django.views.generic.detail.BaseDetailView`
* :class:`django.views.generic.edit.DeletionMixin`
* :class:`django.views.generic.detail.BaseDetailView`
**Notes**
* The delete confirmation page displayed to a GET request uses a
``template_name_suffix`` of ``'_confirm_delete'``.
* The delete confirmation page displayed to a GET request uses a
``template_name_suffix`` of ``'_confirm_delete'``.
Date-based views
----------------
@ -1107,13 +1107,13 @@ ArchiveIndexView
**Mixins**
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
**Notes**
* Uses a default ``context_object_name`` of ``latest``.
* Uses a default ``template_name_suffix`` of ``_archive``.
* Uses a default ``context_object_name`` of ``latest``.
* Uses a default ``template_name_suffix`` of ``_archive``.
YearArchiveView
~~~~~~~~~~~~~~~
@ -1131,9 +1131,9 @@ YearArchiveView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.BaseDateListView`
.. attribute:: make_object_list
@ -1154,15 +1154,15 @@ YearArchiveView
:class:`django.views.generic.dates.BaseDateListView`), the template's
context will be:
* ``date_list``: A ``DateQuerySet`` object containing all months that
have objects available according to ``queryset``, represented as
``datetime.datetime`` objects, in ascending order.
* ``date_list``: A ``DateQuerySet`` object containing all months that
have objects available according to ``queryset``, represented as
``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**
* Uses a default ``template_name_suffix`` of ``_archive_year``.
* Uses a default ``template_name_suffix`` of ``_archive_year``.
MonthArchiveView
~~~~~~~~~~~~~~~~
@ -1181,10 +1181,10 @@ MonthArchiveView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView`
**Context**
@ -1193,23 +1193,23 @@ MonthArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be:
* ``date_list``: A ``DateQuerySet`` object containing all days that
have objects available in the given month, according to ``queryset``,
represented as ``datetime.datetime`` objects, in ascending order.
* ``date_list``: A ``DateQuerySet`` object containing all days that
have objects available in the given month, according to ``queryset``,
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
of the next month. If the next month is in the future, this will be
``None``.
* ``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
``None``.
* ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be
``None``.
* ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be
``None``.
**Notes**
* Uses a default ``template_name_suffix`` of ``_archive_month``.
* Uses a default ``template_name_suffix`` of ``_archive_month``.
WeekArchiveView
~~~~~~~~~~~~~~~
@ -1227,10 +1227,10 @@ WeekArchiveView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.BaseDateListView`
**Context**
@ -1239,12 +1239,12 @@ WeekArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be:
* ``week``: A ``datetime.date`` object representing the first day of
the given week.
* ``week``: A ``datetime.date`` object representing the first day of
the given week.
**Notes**
* Uses a default ``template_name_suffix`` of ``_archive_week``.
* Uses a default ``template_name_suffix`` of ``_archive_week``.
DayArchiveView
~~~~~~~~~~~~~~
@ -1262,11 +1262,11 @@ DayArchiveView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.DayMixin`
* :class:`django.views.generic.dates.BaseDateListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.DayMixin`
* :class:`django.views.generic.dates.BaseDateListView`
**Context**
@ -1275,25 +1275,25 @@ DayArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's
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.
If the next day is in the future, this will be ``None``.
* ``next_day``: A ``datetime.date`` object representing the next day.
If the next day is in the future, this will be ``None``.
* ``previous_day``: A ``datetime.date`` object representing the
previous day. Unlike ``next_day``, this will never be ``None``.
* ``previous_day``: A ``datetime.date`` object representing the
previous day. Unlike ``next_day``, this will never be ``None``.
* ``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
``None``.
* ``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
``None``.
* ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be
``None``.
* ``previous_month``: A ``datetime.date`` object representing the first
day of the previous month. Unlike ``next_month``, this will never be
``None``.
**Notes**
* Uses a default ``template_name_suffix`` of ``_archive_day``.
* Uses a default ``template_name_suffix`` of ``_archive_day``.
TodayArchiveView
~~~~~~~~~~~~~~~~
@ -1311,8 +1311,8 @@ TodayArchiveView
**Mixins**
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.BaseDayArchiveView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
* :class:`django.views.generic.dates.BaseDayArchiveView`
DateDetailView
~~~~~~~~~~~~~~
@ -1330,9 +1330,9 @@ DateDetailView
**Mixins**
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
* :class:`django.views.generic.detail.BaseDetailView`
* :class:`django.views.generic.dates.DateMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :class:`django.views.generic.dates.DayMixin`
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
* :class:`django.views.generic.detail.BaseDetailView`
* :class:`django.views.generic.dates.DateMixin`
* :class:`django.views.generic.dates.YearMixin`
* :class:`django.views.generic.dates.MonthMixin`
* :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
three arguments:
* The current :class:`ModelAdmin`
* An :class:`~django.http.HttpRequest` representing the current request,
* A :class:`~django.db.models.query.QuerySet` containing the set of
objects selected by the user.
* The current :class:`ModelAdmin`
* An :class:`~django.http.HttpRequest` representing the current request,
* A :class:`~django.db.models.query.QuerySet` containing the set of
objects selected by the user.
Our publish-these-articles function won't need the :class:`ModelAdmin` or the
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
the following:
* Add :mod:`django.contrib.admindocs` to your :setting:`INSTALLED_APPS`.
* Add ``(r'^admin/doc/', include('django.contrib.admindocs.urls'))`` to
your :data:`urlpatterns`. Make sure it's included *before* the
``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get
handled by the latter entry.
* Install the docutils Python module (http://docutils.sf.net/).
* **Optional:** Linking to templates requires the :setting:`ADMIN_FOR`
setting to be configured.
* **Optional:** Using the admindocs bookmarklets requires the
:mod:`XViewMiddleware<django.middleware.doc>` to be installed.
* Add :mod:`django.contrib.admindocs` to your :setting:`INSTALLED_APPS`.
* Add ``(r'^admin/doc/', include('django.contrib.admindocs.urls'))`` to
your :data:`urlpatterns`. Make sure it's included *before* the
``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get
handled by the latter entry.
* Install the docutils Python module (http://docutils.sf.net/).
* **Optional:** Linking to templates requires the :setting:`ADMIN_FOR`
setting to be configured.
* **Optional:** Using the admindocs bookmarklets requires the
:mod:`XViewMiddleware<django.middleware.doc>` to be installed.
Once those steps are complete, you can start browsing the documentation by
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
you can document in your view function docstrings include:
* A short description of what the view does.
* 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.
* A short description of what the view does.
* 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.
For example::
@ -141,16 +141,16 @@ Included Bookmarklets
Several useful bookmarklets are available from the ``admindocs`` page:
Documentation for this page
Jumps you from any page to the documentation for the view that generates
that page.
Documentation for this page
Jumps you from any page to the documentation for the view that generates
that page.
Show object ID
Shows the content-type and unique ID for pages that represent a single
object.
Show object ID
Shows the content-type and unique ID for pages that represent a single
object.
Edit this object
Jumps to the admin page for pages that represent a single object.
Edit this object
Jumps to the admin page for pages that represent a single object.
Using these bookmarklets requires that you are either logged into the
: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
that the :mod:`django.middleware.doc` middleware and
: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:
#. Create a custom comment :class:`~django.db.models.Model` that adds on the
"title" field.
#. Create a custom comment :class:`~django.db.models.Model` that adds on the
"title" field.
#. Create a custom comment :class:`~django.forms.Form` that also adds this
"title" field.
#. Create a custom comment :class:`~django.forms.Form` that also adds this
"title" field.
#. Inform Django of these objects by defining a few functions in a
custom :setting:`COMMENTS_APP`.
#. Inform Django of these objects by defining a few functions in a
custom :setting:`COMMENTS_APP`.
So, carrying on the example above, we're dealing with a typical app structure in
the ``my_custom_app`` directory::

View File

@ -22,23 +22,23 @@ Quick start guide
To get started using the ``comments`` app, follow these steps:
#. Install the comments framework by adding ``'django.contrib.comments'`` to
:setting:`INSTALLED_APPS`.
#. Install the comments framework by adding ``'django.contrib.comments'`` to
: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('',
...
(r'^comments/', include('django.contrib.comments.urls')),
...
)
urlpatterns = patterns('',
...
(r'^comments/', include('django.contrib.comments.urls')),
...
)
#. Use the `comment template tags`_ below to embed comments in your
templates.
#. Use the `comment template tags`_ below to embed comments in your
templates.
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
different ways you can specify which object to attach to:
#. 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
to attach the comment to; you can simply use that object.
#. 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
to attach the comment to; you can simply use that object.
For example, in a blog entry page that has a variable named ``entry``,
you could use the following to load the number of comments::
For example, in a blog entry page that has a variable named ``entry``,
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
if you, for some reason, don't actually have direct access to the object.
#. 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.
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::
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::
{% 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
name of the model class.
In the above, ``blog.entry`` is the app label and (lower-cased) model
name of the model class.
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
should know about:
* It contains a number of hidden fields that contain timestamps, information
about the object the comment should be attached to, and a "security hash"
used to validate this information. If someone tampers with this data --
something comment spammers will try -- the comment submission will fail.
* It contains a number of hidden fields that contain timestamps, information
about the object the comment should be attached to, and a "security hash"
used to validate this information. If someone tampers with this data --
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
pass these values through unchanged.
If you're rendering a custom comment form, you'll need to make sure to
pass these values through unchanged.
* 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
comment will have their submissions refused.
* 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
comment will have their submissions refused.
* 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
automatically fill in all fields in an attempt to make valid submissions).
* 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
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
it with a warning field; if you use the comment form with a custom
template you should be sure to do the same.
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
template you should be sure to do the same.
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

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.
Arguments sent with this signal:
``sender``
The comment model.
``comment``
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
relations might not work correctly yet.
``request``
The :class:`~django.http.HttpRequest` that posted the comment.
``sender``
The comment model.
``comment``
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
relations might not work correctly yet.
``request``
The :class:`~django.http.HttpRequest` that posted the comment.
comment_was_posted
==================
.. data:: django.contrib.comments.signals.comment_was_posted
:module:
Sent just after the comment is saved.
Arguments sent with this signal:
``sender``
The comment model.
``comment``
The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again.
``request``
The :class:`~django.http.HttpRequest` that posted the comment.
``sender``
The comment model.
``comment``
The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again.
``request``
The :class:`~django.http.HttpRequest` that posted the comment.
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.
Arguments sent with this signal:
``sender``
The comment model.
``comment``
The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again.
``flag``
The :class:`~django.contrib.comments.models.CommentFlag` that's been
attached to the comment.
``created``
``True`` if this is a new flag; ``False`` if it's a duplicate flag.
``request``
The :class:`~django.http.HttpRequest` that posted the comment.
``sender``
The comment model.
``comment``
The comment instance that was posted. Note that it will have already
been saved, so if you modify it you'll need to call
:meth:`~django.db.models.Model.save` again.
``flag``
The :class:`~django.contrib.comments.models.CommentFlag` that's been
attached to the comment.
``created``
``True`` if this is a new flag; ``False`` if it's a duplicate flag.
``request``
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:
* This new system is documented.
* It uses modern Django features like :doc:`forms </topics/forms/index>` and
:doc:`modelforms </topics/forms/modelforms>`.
* This new system is documented.
* It has a single ``Comment`` model instead of separate ``FreeComment`` and
``Comment`` models.
* It uses modern Django features like :doc:`forms </topics/forms/index>` and
: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
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::
* No ratings, photos and karma. This should only effect World Online.
(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
--------------

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
installed; several of Django's other bundled applications require it:
* The admin application uses it to log the history of each object
added or changed through the admin interface.
* The admin application uses it to log the history of each object
added or changed through the admin interface.
* Django's :mod:`authentication framework <django.contrib.auth>` uses it
to tie user permissions to specific models.
* Django's :mod:`authentication framework <django.contrib.auth>` uses it
to tie user permissions to specific models.
* Django's comments system (:mod:`django.contrib.comments`) uses it to
"attach" comments to any installed model.
* Django's comments system (:mod:`django.contrib.comments`) uses it to
"attach" comments to any installed model.
.. 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
created with the following values:
* :attr:`~django.contrib.contenttypes.models.ContentType.app_label`
will be set to ``'sites'`` (the last part of the Python
path "django.contrib.sites").
* :attr:`~django.contrib.contenttypes.models.ContentType.app_label`
will be set to ``'sites'`` (the last part of the Python
path "django.contrib.sites").
* :attr:`~django.contrib.contenttypes.models.ContentType.model`
will be set to ``'site'``.
* :attr:`~django.contrib.contenttypes.models.ContentType.model`
will be set to ``'site'``.
* :attr:`~django.contrib.contenttypes.models.ContentType.name`
will be set to ``'site'``.
* :attr:`~django.contrib.contenttypes.models.ContentType.name`
will be set to ``'site'``.
.. _the verbose_name attribute: ../model-api/#verbose_name
@ -148,17 +148,17 @@ Together,
and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable
two extremely important use cases:
1. Using these methods, you can write high-level generic code that
performs queries on any installed model -- instead of importing and
using a single specific model class, you can pass an ``app_label`` and
``model`` into a
:class:`~django.contrib.contenttypes.models.ContentType` lookup at
runtime, and then work with the model class or retrieve objects from it.
1. Using these methods, you can write high-level generic code that
performs queries on any installed model -- instead of importing and
using a single specific model class, you can pass an ``app_label`` and
``model`` into a
:class:`~django.contrib.contenttypes.models.ContentType` lookup at
runtime, and then work with the model class or retrieve objects from it.
2. You can relate another model to
:class:`~django.contrib.contenttypes.models.ContentType` as a way of
tying instances of it to particular model classes, and use these methods
to get access to those model classes.
2. You can relate another model to
:class:`~django.contrib.contenttypes.models.ContentType` as a way of
tying instances of it to particular model classes, and use these methods
to get access to those model classes.
Several of Django's bundled applications make use of the latter technique.
For example,
@ -263,21 +263,21 @@ model:
There are three parts to setting up a
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`:
1. Give your model a :class:`~django.db.models.ForeignKey`
to :class:`~django.contrib.contenttypes.models.ContentType`.
1. Give your model a :class:`~django.db.models.ForeignKey`
to :class:`~django.contrib.contenttypes.models.ContentType`.
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
:class:`~django.db.models.PositiveIntegerField`. The usual name
for this field is "object_id".
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
:class:`~django.db.models.PositiveIntegerField`. The usual name
for this field is "object_id".
3. Give your model a
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and
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 the default field names
:class:`~django.contrib.contenttypes.generic.GenericForeignKey` will
look for.
3. Give your model a
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and
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 the default field names
:class:`~django.contrib.contenttypes.generic.GenericForeignKey` will
look for.
.. 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:
1. Add the middleware
``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of
middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come
before any view middleware that assume that CSRF attacks have
been dealt with.)
1. Add the middleware
``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of
middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come
before any view middleware that assume that CSRF attacks have
been dealt with.)
Alternatively, you can use the decorator
:func:`~django.views.decorators.csrf.csrf_protect` on particular views
you want to protect (see below).
Alternatively, you can use the decorator
:func:`~django.views.decorators.csrf.csrf_protect` on particular views
you want to protect (see below).
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.::
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.::
<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
that would cause the CSRF token to be leaked, leading to a vulnerability.
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.
3. In the corresponding view functions, ensure that the
``'django.core.context_processors.csrf'`` context processor is
being used. Usually, this can be done in one of two ways:
3. In the corresponding view functions, ensure that the
``'django.core.context_processors.csrf'`` context processor is
being used. Usually, this can be done in one of two ways:
1. Use RequestContext, which always uses
``'django.core.context_processors.csrf'`` (no matter what your
TEMPLATE_CONTEXT_PROCESSORS setting). If you are using
generic views or contrib apps, you are covered already, since these
apps use RequestContext throughout.
1. Use RequestContext, which always uses
``'django.core.context_processors.csrf'`` (no matter what your
TEMPLATE_CONTEXT_PROCESSORS setting). If you are using
generic views or contrib apps, you are covered already, since these
apps use RequestContext throughout.
2. Manually import and use the processor to generate the CSRF token and
add it to the template context. e.g.::
2. Manually import and use the processor to generate the CSRF token and
add it to the template context. e.g.::
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)
def my_view(request):
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)
You may want to write your own
:func:`~django.shortcuts.render_to_response()` wrapper that takes care
of this step for you.
You may want to write your own
:func:`~django.shortcuts.render_to_response()` wrapper that takes care
of this step for you.
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

View File

@ -17,45 +17,45 @@ introspecting your models.
How to use Databrowse
=====================
1. Point Django at the default Databrowse templates. There are two ways to
do this:
1. Point Django at the default Databrowse templates. There are two ways to
do this:
* Add ``'django.contrib.databrowse'`` to your :setting:`INSTALLED_APPS`
setting. This will work if your :setting:`TEMPLATE_LOADERS` setting
includes the ``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>` for
more.
* Add ``'django.contrib.databrowse'`` to your :setting:`INSTALLED_APPS`
setting. This will work if your :setting:`TEMPLATE_LOADERS` setting
includes the ``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>` for
more.
* Otherwise, determine the full filesystem path to the
:file:`django/contrib/databrowse/templates` directory, and add that
directory to your :setting:`TEMPLATE_DIRS` setting.
* Otherwise, determine the full filesystem path to the
:file:`django/contrib/databrowse/templates` directory, and add that
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 myapp.models import SomeModel, SomeOtherModel
from django.contrib import databrowse
from myapp.models import SomeModel, SomeOtherModel
databrowse.site.register(SomeModel)
databrowse.site.register(SomeOtherModel)
databrowse.site.register(SomeModel)
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
point. A good place for it is in your :doc:`URLconf file
</topics/http/urls>` (``urls.py``).
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
</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
whatever you'd like.
The prefix doesn't matter -- you can use ``databrowse/`` or ``db/`` or
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
====================

View File

@ -22,30 +22,30 @@ content in a custom template.
Here are some examples of flatpages on Django-powered sites:
* http://www.lawrence.com/about/contact/
* http://www2.ljworld.com/site/rules/
* http://www.lawrence.com/about/contact/
* http://www2.ljworld.com/site/rules/
Installation
============
To install the flatpages app, follow these steps:
1. Install the :mod:`sites framework <django.contrib.sites>` by adding
``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting,
if it's not already in there.
1. Install the :mod:`sites framework <django.contrib.sites>` by adding
``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting,
if it's not already in there.
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_ID = 1``, but if you're using the sites framework to manage
multiple sites, it could be the ID of a different site.
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_ID = 1``, but if you're using the sites framework to manage
multiple sites, it could be the ID of a different site.
2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS`
setting.
2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS`
setting.
3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
to your :setting:`MIDDLEWARE_CLASSES` setting.
3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
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
@ -69,13 +69,13 @@ does all of the work.
If it finds a match, it follows this algorithm:
* If the flatpage has a custom template, it loads that template.
Otherwise, it loads the template :file:`flatpages/default.html`.
* If the flatpage has a custom template, it loads that template.
Otherwise, it loads the template :file:`flatpages/default.html`.
* It passes that template a single context variable, ``flatpage``,
which is the flatpage object. It uses
:class:`~django.template.RequestContext` in rendering the
template.
* It passes that template a single context variable, ``flatpage``,
which is the flatpage object. It uses
:class:`~django.template.RequestContext` in rendering the
template.
.. versionchanged:: 1.4
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
application takes care of the following workflow:
1. Displays the form as HTML on a Web page.
2. Validates the form data when it's submitted via POST.
a. If it's valid, displays a preview page.
b. If it's not valid, redisplays the form with error messages.
3. When the "confirmation" form is submitted from the preview page, calls
a hook that you define -- a
:meth:`~django.contrib.formtools.preview.FormPreview.done()` method that gets
passed the valid data.
1. Displays the form as HTML on a Web page.
2. Validates the form data when it's submitted via POST.
a. If it's valid, displays a preview page.
b. If it's not valid, redisplays the form with error messages.
3. When the "confirmation" form is submitted from the preview page, calls
a hook that you define -- a
:meth:`~django.contrib.formtools.preview.FormPreview.done()` method that gets
passed the valid data.
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
@ -36,53 +36,53 @@ on the preview page, the form submission will fail the hash-comparison test.
How to use ``FormPreview``
==========================
1. Point Django at the default FormPreview templates. There are two ways to
do this:
1. Point Django at the default FormPreview templates. There are two ways to
do this:
* Add ``'django.contrib.formtools'`` to your
:setting:`INSTALLED_APPS` setting. This will work if your
:setting:`TEMPLATE_LOADERS` setting includes the
``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>`
for more.
* Add ``'django.contrib.formtools'`` to your
:setting:`INSTALLED_APPS` setting. This will work if your
:setting:`TEMPLATE_LOADERS` setting includes the
``app_directories`` template loader (which is the case by
default). See the :ref:`template loader docs <template-loaders>`
for more.
* Otherwise, determine the full filesystem path to the
:file:`django/contrib/formtools/templates` directory, and add that
directory to your :setting:`TEMPLATE_DIRS` setting.
* Otherwise, determine the full filesystem path to the
:file:`django/contrib/formtools/templates` directory, and add that
directory to your :setting:`TEMPLATE_DIRS` setting.
2. Create a :class:`~django.contrib.formtools.preview.FormPreview` subclass that
overrides the :meth:`~django.contrib.formtools.preview.FormPreview.done()`
method::
2. Create a :class:`~django.contrib.formtools.preview.FormPreview` subclass that
overrides the :meth:`~django.contrib.formtools.preview.FormPreview.done()`
method::
from django.contrib.formtools.preview import FormPreview
from myapp.models import SomeModel
from django.contrib.formtools.preview import FormPreview
from myapp.models import SomeModel
class SomeModelFormPreview(FormPreview):
class SomeModelFormPreview(FormPreview):
def done(self, request, cleaned_data):
# Do something with the cleaned_data, then redirect
# to a "success" page.
return HttpResponseRedirect('/form/success')
def done(self, request, cleaned_data):
# Do something with the cleaned_data, then redirect
# to a "success" page.
return HttpResponseRedirect('/form/success')
This method takes an :class:`~django.http.HttpRequest` object and a
dictionary of the form data after it has been validated and cleaned.
It should return an :class:`~django.http.HttpResponseRedirect` that
is the end result of the form being submitted.
This method takes an :class:`~django.http.HttpRequest` object and a
dictionary of the form data after it has been validated and cleaned.
It should return an :class:`~django.http.HttpResponseRedirect` that
is the end result of the form being submitted.
3. Change your URLconf to point to an instance of your
:class:`~django.contrib.formtools.preview.FormPreview` subclass::
3. Change your URLconf to point to an instance of your
:class:`~django.contrib.formtools.preview.FormPreview` subclass::
from myapp.preview import SomeModelFormPreview
from myapp.forms import SomeModelForm
from django import forms
from myapp.preview import SomeModelFormPreview
from myapp.forms import SomeModelForm
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
=======================

View File

@ -24,15 +24,15 @@ How it works
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
submits it.
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
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.
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,
sending an email, or whatever the application needs to do.
1. The user visits the first page of the wizard, fills in the form and
submits it.
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
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.
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,
sending an email, or whatever the application needs to do.
Usage
=====
@ -40,21 +40,21 @@ Usage
This application handles as much machinery for you as possible. Generally,
you just have to do these things:
1. Define a number of :class:`~django.forms.Form` classes -- one per
wizard page.
1. Define a number of :class:`~django.forms.Form` classes -- one per
wizard page.
2. Create a :class:`WizardView` subclass that specifies what to do once
all of your forms have been submitted and validated. This also lets
you override some of the wizard's behavior.
2. Create a :class:`WizardView` subclass that specifies what to do once
all of your forms have been submitted and validated. This also lets
you override some of the wizard's behavior.
3. Create some templates that render the forms. You can define a single,
generic template to handle every one of the forms, or you can define a
specific template for each form.
3. Create some templates that render the forms. You can define a single,
generic template to handle every one of the forms, or you can define a
specific template for each form.
4. Add ``django.contrib.formtools`` to your
:setting:`INSTALLED_APPS` list in your settings file.
4. Add ``django.contrib.formtools`` to your
: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
-------------------------
@ -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
it:
* ``form`` -- The :class:`~django.forms.Form` instance for the current
step (either empty or with errors).
* ``form`` -- The :class:`~django.forms.Form` instance for the current
step (either empty or with errors).
* ``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).
* ``step1`` -- The current step (one-based).
* ``count`` -- The total number of steps.
* ``first`` -- The first step.
* ``last`` -- The last step.
* ``current`` -- The current (or first) step.
* ``next`` -- The next step.
* ``prev`` -- The previous step.
* ``index`` -- The index of the current step.
* ``all`` -- A list of all steps of the wizard.
* ``step0`` -- The current step (zero-based).
* ``step1`` -- The current step (one-based).
* ``count`` -- The total number of steps.
* ``first`` -- The first step.
* ``last`` -- The last step.
* ``current`` -- The current (or first) step.
* ``next`` -- The next step.
* ``prev`` -- The previous step.
* ``index`` -- The index of the current step.
* ``all`` -- A list of all steps of the wizard.
You can supply additional context variables by using the
: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
:meth:`~WizardView.as_view` method:
* ``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
* ``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
Example code for the changed ``urls.py`` file::

View File

@ -23,9 +23,9 @@ number. This follows Associated Press style.
Examples:
* ``1`` becomes ``one``.
* ``2`` becomes ``two``.
* ``10`` becomes ``10``.
* ``1`` becomes ``one``.
* ``2`` becomes ``two``.
* ``10`` becomes ``10``.
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:
* ``4500`` becomes ``4,500``.
* ``45000`` becomes ``45,000``.
* ``450000`` becomes ``450,000``.
* ``4500000`` becomes ``4,500,000``.
* ``4500`` becomes ``4,500``.
* ``45000`` becomes ``45,000``.
* ``450000`` becomes ``450,000``.
* ``4500000`` becomes ``4,500,000``.
:ref:`Format localization <format-localization>` will be respected if enabled,
e.g. with the ``'de'`` language:
* ``45000`` becomes ``'45.000'``.
* ``450000`` becomes ``'450.000'``.
* ``45000`` becomes ``'45.000'``.
* ``450000`` becomes ``'450.000'``.
You can pass in either an integer or a string representation of an integer.
@ -61,18 +61,18 @@ numbers over 1 million.
Examples:
* ``1000000`` becomes ``1.0 million``.
* ``1200000`` becomes ``1.2 million``.
* ``1200000000`` becomes ``1.2 billion``.
* ``1000000`` becomes ``1.0 million``.
* ``1200000`` becomes ``1.2 million``.
* ``1200000000`` becomes ``1.2 billion``.
Values up to 10^100 (Googol) are supported.
:ref:`Format localization <format-localization>` will be respected if enabled,
e.g. with the ``'de'`` language:
* ``1000000`` becomes ``'1,0 Million'``.
* ``1200000`` becomes ``'1,2 Million'``.
* ``1200000000`` becomes ``'1,2 Milliarden'``.
* ``1000000`` becomes ``'1,0 Million'``.
* ``1200000`` becomes ``'1,2 Million'``.
* ``1200000000`` becomes ``'1,2 Milliarden'``.
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):
* ``16 Feb 2007`` becomes ``yesterday``.
* ``17 Feb 2007`` becomes ``today``.
* ``18 Feb 2007`` becomes ``tomorrow``.
* Any other day is formatted according to given argument or the
:setting:`DATE_FORMAT` setting if no argument is given.
* ``16 Feb 2007`` becomes ``yesterday``.
* ``17 Feb 2007`` becomes ``today``.
* ``18 Feb 2007`` becomes ``tomorrow``.
* Any other day is formatted according to given argument or the
:setting:`DATE_FORMAT` setting if no argument is given.
.. 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):
* ``17 Feb 2007 16:30:00`` becomes ``now``.
* ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``.
* ``17 Feb 2007 16:29:00`` becomes ``a minute ago``.
* ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
* ``17 Feb 2007 15:30:29`` becomes ``an hour ago``.
* ``17 Feb 2007 13:31:29`` becomes ``2 hours 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:31:00`` becomes ``a minute 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 18:31:29`` becomes ``2 hours from now``.
* ``18 Feb 2007 16:31:29`` becomes ``1 day from now``.
* ``17 Feb 2007 16:30:00`` becomes ``now``.
* ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``.
* ``17 Feb 2007 16:29:00`` becomes ``a minute ago``.
* ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
* ``17 Feb 2007 15:30:29`` becomes ``an hour ago``.
* ``17 Feb 2007 13:31:29`` becomes ``2 hours 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:31:00`` becomes ``a minute 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 18:31:29`` becomes ``2 hours from now``.
* ``18 Feb 2007 16:31:29`` becomes ``1 day from now``.
.. templatefilter:: ordinal
@ -132,8 +132,8 @@ Converts an integer to its ordinal as a string.
Examples:
* ``1`` becomes ``1st``.
* ``2`` becomes ``2nd``.
* ``3`` becomes ``3rd``.
* ``1`` becomes ``1st``.
* ``2`` becomes ``2nd``.
* ``3`` becomes ``3rd``.
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
languages:
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_
* ``restructuredtext`` -- implements `reST (reStructured Text)`_
-- requires `doc-utils`_
* ``textile`` -- implements `Textile`_ -- requires `PyTextile`_
* ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_
* ``restructuredtext`` -- implements `reST (reStructured Text)`_
-- requires `doc-utils`_
In each case, the filter expects formatted markup as a string and
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:
* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
it contains ``'django.contrib.messages.middleware.MessageMiddleware'``.
* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
it contains ``'django.contrib.messages.middleware.MessageMiddleware'``.
If you are using a :ref:`storage backend <message-storage-backends>` that
relies on :doc:`sessions </topics/http/sessions>` (the default),
``'django.contrib.sessions.middleware.SessionMiddleware'`` must be
enabled and appear before ``MessageMiddleware`` in your
:setting:`MIDDLEWARE_CLASSES`.
If you are using a :ref:`storage backend <message-storage-backends>` that
relies on :doc:`sessions </topics/http/sessions>` (the default),
``'django.contrib.sessions.middleware.SessionMiddleware'`` must be
enabled and appear before ``MessageMiddleware`` in your
:setting:`MIDDLEWARE_CLASSES`.
* Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure
it contains ``'django.contrib.messages.context_processors.messages'``.
* Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure
it contains ``'django.contrib.messages.context_processors.messages'``.
* Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS`
setting
* Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS`
setting
The default ``settings.py`` created by ``django-admin.py startproject`` has
``MessageMiddleware`` activated and the ``django.contrib.messages`` app
@ -349,9 +349,9 @@ Default: ``'django.contrib.messages.storage.user_messages.FallbackStorage'``
Controls where Django stores message data. Valid values are:
* ``'django.contrib.messages.storage.fallback.FallbackStorage'``
* ``'django.contrib.messages.storage.session.SessionStorage'``
* ``'django.contrib.messages.storage.cookie.CookieStorage'``
* ``'django.contrib.messages.storage.fallback.FallbackStorage'``
* ``'django.contrib.messages.storage.session.SessionStorage'``
* ``'django.contrib.messages.storage.cookie.CookieStorage'``
See `Storage backends`_ for more details.

View File

@ -13,11 +13,11 @@ Installation
To install the redirects app, follow these steps:
1. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS`
setting.
2. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'``
to your :setting:`MIDDLEWARE_CLASSES` setting.
3. Run the command :djadmin:`manage.py syncdb <syncdb>`.
1. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS`
setting.
2. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'``
to your :setting:`MIDDLEWARE_CLASSES` setting.
3. Run the command :djadmin:`manage.py syncdb <syncdb>`.
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
:setting:`SITE_ID` setting.
* If it finds a match, and ``new_path`` is not empty, it redirects to
``new_path``.
* If it finds a match, and ``new_path`` is empty, it sends a 410 ("Gone")
HTTP header and empty (content-less) response.
* If it doesn't find a match, the request continues to be processed as
usual.
* If it finds a match, and ``new_path`` is not empty, it redirects to
``new_path``.
* If it finds a match, and ``new_path`` is empty, it sends a 410 ("Gone")
HTTP header and empty (content-less) response.
* If it doesn't find a match, the request continues to be processed as
usual.
The middleware only gets activated for 404s -- not for 500s or responses of any
other status code.

View File

@ -31,15 +31,15 @@ Installation
To install the sitemap app, follow these steps:
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
setting.
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
setting.
2. Make sure ``'django.template.loaders.app_directories.Loader'``
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default,
so you'll only need to change this if you've changed that setting.
2. Make sure ``'django.template.loaders.app_directories.Loader'``
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default,
so you'll only need to change this if you've changed that setting.
3. Make sure you've installed the
:mod:`sites framework <django.contrib.sites>`.
3. Make sure you've installed the
:mod:`sites framework <django.contrib.sites>`.
(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
@ -109,20 +109,20 @@ your sitemap class might look::
Note:
* :attr:`~Sitemap.changefreq` and :attr:`~Sitemap.priority` are class
attributes corresponding to ``<changefreq>`` and ``<priority>`` elements,
respectively. They can be made callable as functions, as
:attr:`~Sitemap.lastmod` was in the example.
* :attr:`~Sitemap.items()` is simply a method that returns a list of
objects. The objects returned will get passed to any callable methods
corresponding to a sitemap property (:attr:`~Sitemap.location`,
:attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and
:attr:`~Sitemap.priority`).
* :attr:`~Sitemap.lastmod` should return a Python ``datetime`` object.
* 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,
:attr:`~Sitemap.location()` calls ``get_absolute_url()`` on each object
and returns the result.
* :attr:`~Sitemap.changefreq` and :attr:`~Sitemap.priority` are class
attributes corresponding to ``<changefreq>`` and ``<priority>`` elements,
respectively. They can be made callable as functions, as
:attr:`~Sitemap.lastmod` was in the example.
* :attr:`~Sitemap.items()` is simply a method that returns a list of
objects. The objects returned will get passed to any callable methods
corresponding to a sitemap property (:attr:`~Sitemap.location`,
:attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and
:attr:`~Sitemap.priority`).
* :attr:`~Sitemap.lastmod` should return a Python ``datetime`` object.
* 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,
:attr:`~Sitemap.location()` calls ``get_absolute_url()`` on each object
and returns the result.
Sitemap class reference
=======================
@ -153,9 +153,9 @@ Sitemap class reference
In both cases, "absolute path" means a URL that doesn't include the
protocol or domain. Examples:
* Good: :file:`'/foo/bar/'`
* Bad: :file:`'example.com/foo/bar/'`
* Bad: :file:`'http://example.com/foo/bar/'`
* Good: :file:`'/foo/bar/'`
* Bad: :file:`'example.com/foo/bar/'`
* Bad: :file:`'http://example.com/foo/bar/'`
If :attr:`~Sitemap.location` isn't provided, the framework will call
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:
* ``'always'``
* ``'hourly'``
* ``'daily'``
* ``'weekly'``
* ``'monthly'``
* ``'yearly'``
* ``'never'``
* ``'always'``
* ``'hourly'``
* ``'daily'``
* ``'weekly'``
* ``'monthly'``
* ``'yearly'``
* ``'never'``
.. 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
:data:`sitemaps` dictionary. The only differences in usage are:
* You use two views in your URLconf: :func:`django.contrib.sitemaps.views.index`
and :func:`django.contrib.sitemaps.views.sitemap`.
* The :func:`django.contrib.sitemaps.views.sitemap` view should take a
:data:`section` keyword argument.
* You use two views in your URLconf: :func:`django.contrib.sitemaps.views.index`
and :func:`django.contrib.sitemaps.views.sitemap`.
* The :func:`django.contrib.sitemaps.views.sitemap` view should take a
:data:`section` keyword argument.
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
:class:`~django.contrib.sitemaps.Sitemap` class:
- ``changefreq``
- ``item``
- ``lastmod``
- ``location``
- ``priority``
- ``changefreq``
- ``item``
- ``lastmod``
- ``location``
- ``priority``
.. 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:
* It lets the site producers edit all content -- on both sites -- in a
single interface (the Django admin).
* It lets the site producers edit all content -- on both sites -- in a
single interface (the Django admin).
* It means the same story doesn't have to be published twice in the
database; it only has a single record in the database.
* It means the same story doesn't have to be published twice in the
database; it only has a single record in the database.
* 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
requested story is on the current site. It looks something like this::
* 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
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):
try:
a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID)
except Article.DoesNotExist:
raise Http404
# ...
def article_detail(request, article_id):
try:
a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID)
except Article.DoesNotExist:
raise Http404
# ...
.. _ljworld.com: http://www.ljworld.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
files:
- The :func:`django.core.context_processors.static` context processor
which adds :setting:`STATIC_URL` to every template context rendered
with :class:`~django.template.RequestContext` contexts.
- The :func:`django.core.context_processors.static` context processor
which adds :setting:`STATIC_URL` to every template context rendered
with :class:`~django.template.RequestContext` contexts.
- The builtin template tag :ttag:`static` which takes a path and
urljoins it with the static prefix :setting:`STATIC_URL`.
- The builtin template tag :ttag:`static` which takes a path and
urljoins it with the static prefix :setting:`STATIC_URL`.
- The builtin template tag :ttag:`get_static_prefix` which populates a
template variable with the static prefix :setting:`STATIC_URL` to be
used as a variable or directly.
- The builtin template tag :ttag:`get_static_prefix` which populates a
template variable with the static prefix :setting:`STATIC_URL` to be
used as a variable or directly.
- The similar template tag :ttag:`get_media_prefix` which works like
:ttag:`get_static_prefix` but uses :setting:`MEDIA_URL`.
- The similar template tag :ttag:`get_media_prefix` which works like
:ttag:`get_static_prefix` but uses :setting:`MEDIA_URL`.
.. _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
into those elements.
* For the contents of ``<title>`` and ``<description>``, Django tries
calling the methods ``item_title()`` and ``item_description()`` on
the :class:`~django.contrib.syndication.views.Feed` class. They are passed
a single parameter, ``item``, which is the object itself. These are
optional; by default, the unicode representation of the object is used for
both.
* For the contents of ``<title>`` and ``<description>``, Django tries
calling the methods ``item_title()`` and ``item_description()`` on
the :class:`~django.contrib.syndication.views.Feed` class. They are passed
a single parameter, ``item``, which is the object itself. These are
optional; by default, the unicode representation of the object is used for
both.
If you want to do any special formatting for either the title or
description, :doc:`Django templates </topics/templates>` can be used
instead. Their paths can be specified with the ``title_template`` and
``description_template`` attributes on the
:class:`~django.contrib.syndication.views.Feed` class. The templates are
rendered for each item and are passed two template context variables:
If you want to do any special formatting for either the title or
description, :doc:`Django templates </topics/templates>` can be used
instead. Their paths can be specified with the ``title_template`` and
``description_template`` attributes on the
:class:`~django.contrib.syndication.views.Feed` class. The templates are
rendered for each item and are passed two template context variables:
* ``{{ obj }}`` -- The current object (one of whichever objects you
returned in ``items()``).
* ``{{ obj }}`` -- The current object (one of whichever objects you
returned in ``items()``).
* ``{{ site }}`` -- A :class:`django.contrib.sites.models.Site` object
representing the current site. This is useful for ``{{ site.domain
}}`` or ``{{ site.name }}``. If you do *not* have the Django sites
framework installed, this will be set to a
:class:`django.contrib.sites.models.RequestSite` object. See the
:ref:`RequestSite section of the sites framework documentation
<requestsite-objects>` for more.
* ``{{ site }}`` -- A :class:`django.contrib.sites.models.Site` object
representing the current site. This is useful for ``{{ site.domain
}}`` or ``{{ site.name }}``. If you do *not* have the Django sites
framework installed, this will be set to a
:class:`django.contrib.sites.models.RequestSite` object. See the
:ref:`RequestSite section of the sites framework documentation
<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
in ``items()``, Django first tries calling the
``item_link()`` method on the
:class:`~django.contrib.syndication.views.Feed` class. In a similar way to
the title and description, it is passed it a single parameter,
``item``. If that method doesn't exist, Django tries executing a
``get_absolute_url()`` method on that object. Both
``get_absolute_url()`` and ``item_link()`` should return 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
are responsible for doing all necessary URL quoting and conversion to
ASCII inside the method itself.
* To specify the contents of ``<link>``, you have two options. For each item
in ``items()``, Django first tries calling the
``item_link()`` method on the
:class:`~django.contrib.syndication.views.Feed` class. In a similar way to
the title and description, it is passed it a single parameter,
``item``. If that method doesn't exist, Django tries executing a
``get_absolute_url()`` method on that object. Both
``get_absolute_url()`` and ``item_link()`` should return 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
are responsible for doing all necessary URL quoting and conversion to
ASCII inside the method itself.
.. _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:
* :file:`/beats/613/rss/` -- Returns recent crimes for beat 613.
* :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424.
* :file:`/beats/613/rss/` -- Returns recent crimes for beat 613.
* :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424.
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
algorithm:
* First, it tries to call a method, passing the ``obj`` argument, where
``obj`` is the object returned by ``get_object()``.
* First, it tries to call a method, passing the ``obj`` argument, where
``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
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:
* :class:`django.utils.feedgenerator.Rss201rev2Feed` (RSS 2.01. Default.)
* :class:`django.utils.feedgenerator.RssUserland091Feed` (RSS 0.91.)
* :class:`django.utils.feedgenerator.Atom1Feed` (Atom 1.0.)
* :class:`django.utils.feedgenerator.Rss201rev2Feed` (RSS 2.01. Default.)
* :class:`django.utils.feedgenerator.RssUserland091Feed` (RSS 0.91.)
* :class:`django.utils.feedgenerator.Atom1Feed` (Atom 1.0.)
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:
* :class:`django.utils.feedgenerator.SyndicationFeed`
* :class:`django.utils.feedgenerator.SyndicationFeed`
and several subclasses:
* :class:`django.utils.feedgenerator.RssUserland091Feed`
* :class:`django.utils.feedgenerator.Rss201rev2Feed`
* :class:`django.utils.feedgenerator.Atom1Feed`
* :class:`django.utils.feedgenerator.RssUserland091Feed`
* :class:`django.utils.feedgenerator.Rss201rev2Feed`
* :class:`django.utils.feedgenerator.Atom1Feed`
Each of these three classes knows how to render a certain type of feed as XML.
They share this interface:
@ -803,22 +803,22 @@ They share this interface:
Initialize the feed with the given dictionary of metadata, which applies to
the entire feed. Required keyword arguments are:
* ``title``
* ``link``
* ``description``
* ``title``
* ``link``
* ``description``
There's also a bunch of other optional keywords:
* ``language``
* ``author_email``
* ``author_name``
* ``author_link``
* ``subtitle``
* ``categories``
* ``feed_url``
* ``feed_copyright``
* ``feed_guid``
* ``ttl``
* ``language``
* ``author_email``
* ``author_name``
* ``author_link``
* ``subtitle``
* ``categories``
* ``feed_url``
* ``feed_copyright``
* ``feed_guid``
* ``ttl``
Any extra keyword arguments you pass to ``__init__`` will be stored in
``self.feed`` for use with `custom feed generators`_.
@ -831,31 +831,31 @@ They share this interface:
Required keyword arguments are:
* ``title``
* ``link``
* ``description``
* ``title``
* ``link``
* ``description``
Optional keyword arguments are:
* ``author_email``
* ``author_name``
* ``author_link``
* ``pubdate``
* ``comments``
* ``unique_id``
* ``enclosure``
* ``categories``
* ``item_copyright``
* ``ttl``
* ``author_email``
* ``author_name``
* ``author_link``
* ``pubdate``
* ``comments``
* ``unique_id``
* ``enclosure``
* ``categories``
* ``item_copyright``
* ``ttl``
Extra keyword arguments will be stored for `custom feed generators`_.
All parameters, if given, should be Unicode objects, except:
* ``pubdate`` should be a Python :class:`~datetime.datetime` object.
* ``enclosure`` should be an instance of
:class:`django.utils.feedgenerator.Enclosure`.
* ``categories`` should be a sequence of Unicode objects.
* ``pubdate`` should be a Python :class:`~datetime.datetime` object.
* ``enclosure`` should be an instance of
:class:`django.utils.feedgenerator.Enclosure`.
* ``categories`` should be a sequence of Unicode objects.
:meth:`.SyndicationFeed.write`
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 arguments are:
=========== =============================================================
Argument Description
=========== =============================================================
``count`` A number (or variable) containing the number of paragraphs or
words to generate (default is 1).
``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b``
for plain-text paragraph blocks (default is ``b``).
``random`` The word ``random``, which if given, does not use the common
paragraph ("Lorem ipsum dolor sit amet...") when generating
text.
=========== =============================================================
=========== =============================================================
Argument Description
=========== =============================================================
``count`` A number (or variable) containing the number of paragraphs or
words to generate (default is 1).
``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b``
for plain-text paragraph blocks (default is ``b``).
``random`` The word ``random``, which if given, does not use the common
paragraph ("Lorem ipsum dolor sit amet...") when generating
text.
=========== =============================================================
Examples:
* ``{% lorem %}`` 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.
* ``{% lorem 2 w random %}`` will output two random Latin words.
* ``{% lorem %}`` 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.
* ``{% 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:
1. :setting:`OPTIONS`.
2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
:setting:`HOST`, :setting:`PORT`
3. MySQL option files.
1. :setting:`OPTIONS`.
2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`,
:setting:`HOST`, :setting:`PORT`
3. MySQL option files.
In other words, if you set the name of the database in :setting:`OPTIONS`,
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
storage engine, you have a couple of options.
* After the tables are created, execute an ``ALTER TABLE`` statement to
convert a table to a new storage engine (such as InnoDB)::
* After the tables are created, execute an ``ALTER TABLE`` statement to
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
creating your tables::
* Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables::
'OPTIONS': {
'init_command': 'SET storage_engine=INNODB',
}
'OPTIONS': {
'init_command': 'SET storage_engine=INNODB',
}
This sets the default storage engine upon connecting to the database.
After your tables have been created, you should remove this option.
This sets the default storage engine upon connecting to the database.
After your tables have been created, you should remove this option.
* Another method for changing the storage engine is described in
AlterModelOnSyncDB_.
* Another method for changing the storage engine is described in
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:
* A bug when `handling`_ ``ORDER BY`` parameters. This can cause problems when
you use the ``select`` parameter for the ``extra()`` QuerySet method. The bug
can be identified by the error message ``OperationalError: ORDER BY terms
must not be non-integer constants``.
* A bug when `handling`_ ``ORDER BY`` parameters. This can cause problems when
you use the ``select`` parameter for the ``extra()`` QuerySet method. The bug
can be identified by the error message ``OperationalError: ORDER BY terms
must not be non-integer constants``.
* A bug when handling `aggregation`_ together with DateFields and
DecimalFields.
* A bug when handling `aggregation`_ together with DateFields and
DecimalFields.
.. _handling: http://www.sqlite.org/cvstrac/tktview?tn=1768
.. _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:
* Switching to another database backend. At a certain point SQLite becomes
too "lite" for real-world applications, and these sorts of concurrency
errors indicate you've reached that point.
* Switching to another database backend. At a certain point SQLite becomes
too "lite" for real-world applications, and these sorts of concurrency
errors indicate you've reached that point.
* Rewriting your code to reduce concurrency and ensure that database
transactions are short-lived.
* Rewriting your code to reduce concurrency and ensure that database
transactions are short-lived.
* Increase the default timeout value by setting the ``timeout`` database
option option::
* Increase the default timeout value by setting the ``timeout`` database
option option::
'OPTIONS': {
# ...
'timeout': 20,
# ...
}
'OPTIONS': {
# ...
'timeout': 20,
# ...
}
This will simply make SQLite wait a bit longer before throwing "database
is locked" errors; it won't really do anything to solve them.
This will simply make SQLite wait a bit longer before throwing "database
is locked" errors; it won't really do anything to solve them.
``QuerySet.select_for_update()`` not supported
----------------------------------------------
@ -567,19 +567,19 @@ required.
In order for the ``python manage.py syncdb`` command to work, your Oracle
database user must have privileges to run the following commands:
* CREATE TABLE
* CREATE SEQUENCE
* CREATE PROCEDURE
* CREATE TRIGGER
* CREATE TABLE
* CREATE SEQUENCE
* CREATE PROCEDURE
* CREATE TRIGGER
To run Django's test suite, the user needs these *additional* privileges:
* CREATE USER
* DROP USER
* CREATE TABLESPACE
* DROP TABLESPACE
* CONNECT WITH ADMIN OPTION
* RESOURCE WITH ADMIN OPTION
* CREATE USER
* DROP USER
* CREATE TABLESPACE
* DROP TABLESPACE
* CONNECT WITH ADMIN OPTION
* RESOURCE WITH ADMIN OPTION
Connecting to the database
--------------------------
@ -721,16 +721,16 @@ assumption.
The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes
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
attempting to use the ``QuerySet.distinct`` method on a model that
includes ``TextField`` columns will result in an error when run against
Oracle. As a workaround, use the ``QuerySet.defer`` method in conjunction
with ``distinct()`` to prevent ``TextField`` columns from being included in
the ``SELECT DISTINCT`` list.
* 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
includes ``TextField`` columns will result in an error when run against
Oracle. As a workaround, use the ``QuerySet.defer`` method in conjunction
with ``distinct()`` to prevent ``TextField`` columns from being included in
the ``SELECT DISTINCT`` list.
.. _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
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 points to your project's ``settings.py`` file.
* It sets the :envvar:`DJANGO_SETTINGS_MODULE` environment variable so that
it points to your project's ``settings.py`` file.
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
@ -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
:setting:`USER`, :setting:`PASSWORD`, etc., settings.
* For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` command-line client.
* For SQLite, this runs the ``sqlite3`` command-line client.
* For PostgreSQL, this runs the ``psql`` command-line client.
* For MySQL, this runs the ``mysql`` 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
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
output:
* If ``inspectdb`` cannot map a column's type to a model field type, it'll
use ``TextField`` and will insert the Python comment
``'This field type is a guess.'`` next to the field in the generated
model.
* If ``inspectdb`` cannot map a column's type to a model field type, it'll
use ``TextField`` and will insert the Python comment
``'This field type is a guess.'`` next to the field in the generated
model.
* If the database column name is a Python reserved word (such as
``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append
``'_field'`` to the attribute name. For example, if a table has a column
``'for'``, the generated model will have a field ``'for_field'``, with
the ``db_column`` attribute set to ``'for'``. ``inspectdb`` will insert
the Python comment
``'Field renamed because it was a Python reserved word.'`` next to the
field.
* If the database column name is a Python reserved word (such as
``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append
``'_field'`` to the attribute name. For example, if a table has a column
``'for'``, the generated model will have a field ``'for_field'``, with
the ``db_column`` attribute set to ``'for'``. ``inspectdb`` will insert
the Python comment
``'Field renamed because it was a Python reserved word.'`` next to the
field.
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
@ -309,9 +309,9 @@ fixture can be distributed over multiple directories, in multiple applications.
Django will search in three locations for fixtures:
1. In the ``fixtures`` directory of every installed application
2. In any directory named in the :setting:`FIXTURE_DIRS` setting
3. In the literal path named by the fixture
1. In the ``fixtures`` directory of every installed application
2. In any directory named in the :setting:`FIXTURE_DIRS` setting
3. In the literal path named by the fixture
Django will load any and all fixtures it finds in these locations that match
the provided fixture names.
@ -438,8 +438,8 @@ Example usage::
Use the ``--domain`` or ``-d`` option to change the domain of the messages files.
Currently supported:
* ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default)
* ``djangojs`` for ``*.js`` files
* ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default)
* ``djangojs`` for ``*.js`` files
.. django-admin-option:: --symlinks
@ -984,25 +984,25 @@ For example, this command::
...would perform the following steps:
1. Create a test database, as described in :doc:`/topics/testing`.
2. Populate the test database with fixture data from the given fixtures.
(For more on fixtures, see the documentation for ``loaddata`` above.)
3. Runs the Django development server (as in ``runserver``), pointed at
this newly created test database instead of your production database.
1. Create a test database, as described in :doc:`/topics/testing`.
2. Populate the test database with fixture data from the given fixtures.
(For more on fixtures, see the documentation for ``loaddata`` above.)
3. Runs the Django development server (as in ``runserver``), pointed at
this newly created test database instead of your production database.
This is useful in a number of ways:
* 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
the views in a Web browser, manually.
* 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
the views in a Web browser, manually.
* 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
database to a fixture (using the ``dumpdata`` command, explained above),
then use ``testserver`` to run your Web application with that data. With
this arrangement, you have the flexibility of messing up your data
in any way, knowing that whatever data changes you're making are only
being made to a test database.
* 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
database to a fixture (using the ``dumpdata`` command, explained above),
then use ``testserver`` to run your Web application with that data. With
this arrangement, you have the flexibility of messing up your data
in any way, knowing that whatever data changes you're making are only
being made to a test database.
Note that this server does *not* automatically detect changes to your Python
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
that ``django-admin.py`` should print to the console.
* ``0`` means no output.
* ``1`` means normal output (default).
* ``2`` means verbose output.
* ``3`` means *very* verbose output.
* ``0`` means no output.
* ``1`` means normal output (default).
* ``2`` means verbose output.
* ``3`` means *very* verbose output.
Common options
==============
@ -1259,13 +1259,13 @@ another program.
The colors used for syntax highlighting can be customized. Django
ships with three color palettes:
* ``dark``, suited to terminals that show white text on a black
background. This is the default palette.
* ``dark``, suited to terminals that show white text on a black
background. This is the default palette.
* ``light``, suited to terminals that show black text on a white
background.
* ``light``, suited to terminals that show black text on a white
background.
* ``nocolor``, which disables syntax highlighting.
* ``nocolor``, which disables syntax highlighting.
You select a palette by setting a ``DJANGO_COLORS`` environment
variable to specify the palette you want to use. For example, to
@ -1277,47 +1277,47 @@ would run the following at a command prompt::
You can also customize the colors that are used. Django specifies a
number of roles in which color is used:
* ``error`` - A major error.
* ``notice`` - A minor error.
* ``sql_field`` - The name of a model field in SQL.
* ``sql_coltype`` - The type of a model field in SQL.
* ``sql_keyword`` - A SQL keyword.
* ``sql_table`` - The name of a model in SQL.
* ``http_info`` - A 1XX HTTP Informational server response.
* ``http_success`` - A 2XX HTTP Success server response.
* ``http_not_modified`` - A 304 HTTP Not Modified server response.
* ``http_redirect`` - A 3XX HTTP Redirect server response other than 304.
* ``http_not_found`` - A 404 HTTP Not Found server response.
* ``http_bad_request`` - A 4XX HTTP Bad Request server response other than 404.
* ``http_server_error`` - A 5XX HTTP Server Error response.
* ``error`` - A major error.
* ``notice`` - A minor error.
* ``sql_field`` - The name of a model field in SQL.
* ``sql_coltype`` - The type of a model field in SQL.
* ``sql_keyword`` - A SQL keyword.
* ``sql_table`` - The name of a model in SQL.
* ``http_info`` - A 1XX HTTP Informational server response.
* ``http_success`` - A 2XX HTTP Success server response.
* ``http_not_modified`` - A 304 HTTP Not Modified server response.
* ``http_redirect`` - A 3XX HTTP Redirect server response other than 304.
* ``http_not_found`` - A 404 HTTP Not Found server response.
* ``http_bad_request`` - A 4XX HTTP Bad Request server response other than 404.
* ``http_server_error`` - A 5XX HTTP Server Error response.
Each of these roles can be assigned a specific foreground and
background color, from the following list:
* ``black``
* ``red``
* ``green``
* ``yellow``
* ``blue``
* ``magenta``
* ``cyan``
* ``white``
* ``black``
* ``red``
* ``green``
* ``yellow``
* ``blue``
* ``magenta``
* ``cyan``
* ``white``
Each of these colors can then be modified by using the following
display options:
* ``bold``
* ``underscore``
* ``blink``
* ``reverse``
* ``conceal``
* ``bold``
* ``underscore``
* ``blink``
* ``reverse``
* ``conceal``
A color specification follows one of the following patterns:
* ``role=fg``
* ``role=fg/bg``
* ``role=fg,option,option``
* ``role=fg/bg,option,option``
* ``role=fg``
* ``role=fg/bg``
* ``role=fg,option,option``
* ``role=fg/bg,option,option``
where ``role`` is the name of a valid color role, ``fg`` is the
foreground color, ``bg`` is the background color and each ``option``
@ -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
``manage.py`` commands, so you can, for instance...
* Type ``django-admin.py``.
* Press [TAB] to see all available options.
* Type ``sql``, then [TAB], to see all available options whose names start
with ``sql``.
* Type ``django-admin.py``.
* Press [TAB] to see all available options.
* Type ``sql``, then [TAB], to see all available options whose names start
with ``sql``.
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
model field. This can happen for several reasons:
- A field in a model clashes with a field of the same name from an
abstract base class
- An infinite loop is caused by ordering
- A keyword cannot be parsed from the filter parameters
- A field cannot be determined from a keyword in the query
parameters
- A join is not permitted on the specified field
- A field name is invalid
- A query contains invalid order_by arguments
- A field in a model clashes with a field of the same name from an
abstract base class
- An infinite loop is caused by ordering
- A keyword cannot be parsed from the filter parameters
- A field cannot be determined from a keyword in the query
parameters
- A join is not permitted on the specified field
- A field name is invalid
- A query contains invalid order_by arguments
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**.
* 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.
* 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.
* 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.
* If it's **unbound**, it cannot do validation (because there's no data to
validate!), but it can still render the blank form as HTML.
.. class:: Form
@ -292,29 +292,29 @@ include ``checked="checked"`` if appropriate::
This default output is a two-column HTML table, with a ``<tr>`` for each field.
Notice the following:
* For flexibility, the output does *not* include the ``<table>`` and
``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
tags or an ``<input type="submit">`` tag. It's your job to do that.
* For flexibility, the output does *not* include the ``<table>`` and
``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
tags or an ``<input type="submit">`` tag. It's your job to do that.
* Each field type has a default HTML representation. ``CharField`` and
``EmailField`` are represented by an ``<input type="text">``.
``BooleanField`` is represented by an ``<input type="checkbox">``. Note
these are merely sensible defaults; you can specify which HTML to use for
a given field by using widgets, which we'll explain shortly.
* Each field type has a default HTML representation. ``CharField`` and
``EmailField`` are represented by an ``<input type="text">``.
``BooleanField`` is represented by an ``<input type="checkbox">``. Note
these are merely sensible defaults; you can specify which HTML to use for
a given field by using widgets, which we'll explain shortly.
* The HTML ``name`` for each tag is taken directly from its attribute name
in the ``ContactForm`` class.
* The HTML ``name`` for each tag is taken directly from its attribute name
in the ``ContactForm`` class.
* The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
``'Cc myself:'`` is generated from the field name by converting all
underscores to spaces and upper-casing the first letter. Again, note
these are merely sensible defaults; you can also specify labels manually.
* The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
``'Cc myself:'`` is generated from the field name by converting all
underscores to spaces and upper-casing the first letter. Again, note
these are merely sensible defaults; you can also specify labels manually.
* 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
generated by prepending ``'id_'`` to the field name. The ``id``
attributes and ``<label>`` tags are included in the output by default, to
follow best practices, but you can change that behavior.
* 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
generated by prepending ``'id_'`` to the field name. The ``id``
attributes and ``<label>`` tags are included in the output by default, to
follow best practices, but you can change that behavior.
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

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``.
* Error message keys: ``required``
.. note::
.. note::
Since all ``Field`` subclasses have ``required=True`` by default, the
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
unchecked checkbox), you must remember to pass in ``required=False`` when
creating the ``BooleanField``.
Since all ``Field`` subclasses have ``required=True`` by default, the
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
unchecked checkbox), you must remember to pass in ``required=False`` when
creating the ``BooleanField``.
``CharField``
~~~~~~~~~~~~~
@ -322,10 +322,10 @@ For each field, we describe the default widget used if you don't specify
Otherwise, all inputs are valid.
* 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:: CharField.min_length
.. attribute:: max_length
.. attribute:: min_length
If provided, these arguments ensure that the string is at most or at least
the given length.
@ -341,25 +341,25 @@ Has two optional arguments for validation:
* Validates that the given value exists in the list of choices.
* Error message keys: ``required``, ``invalid_choice``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice.
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
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
field. This argument accepts the same formats as the ``choices`` argument
to a model field. See the :ref:`model field reference documentation on
choices <field-choices>` for more details.
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
to a model field. See the :ref:`model field reference documentation on
choices <field-choices>` for more details.
``TypedChoiceField``
~~~~~~~~~~~~~~~~~~~~
.. class:: TypedChoiceField(**kwargs)
Just like a :class:`ChoiceField`, except :class:`TypedChoiceField` takes two
extra arguments, ``coerce`` and ``empty_value``.
Just like a :class:`ChoiceField`, except :class:`TypedChoiceField` takes two
extra arguments, ``coerce`` and ``empty_value``.
* Default widget: ``Select``
* Empty value: Whatever you've given as ``empty_value``
@ -368,20 +368,20 @@ extra arguments, ``coerce`` and ``empty_value``.
coerced.
* 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
include the built-in ``int``, ``float``, ``bool`` and other types. Defaults
to an identity function.
A function that takes one argument and returns a coerced value. Examples
include the built-in ``int``, ``float``, ``bool`` and other types. Defaults
to an identity function.
.. attribute:: TypedChoiceField.empty_value
.. attribute:: empty_value
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
coerced by the function given in the ``coerce`` argument, so choose it
accordingly.
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
coerced by the function given in the ``coerce`` argument, so choose it
accordingly.
``DateField``
~~~~~~~~~~~~~
@ -395,20 +395,20 @@ Takes extra arguments:
``datetime.datetime`` or string formatted in a particular date format.
* 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
``datetime.date`` object.
A list of formats used to attempt to convert a string to a valid
``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'
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 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'
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
'%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'
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 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'
``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.
* 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
``datetime.datetime`` object.
A list of formats used to attempt to convert a string to a valid
``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', # '2006-10-25 14:30'
'%Y-%m-%d', # '2006-10-25'
'%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', # '10/25/2006'
'%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', # '10/25/06'
'%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', # '2006-10-25'
'%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', # '10/25/2006'
'%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', # '10/25/06'
``DecimalField``
~~~~~~~~~~~~~~~~
@ -455,26 +455,26 @@ If no ``input_formats`` argument is provided, the default input formats are::
``min_value``, ``max_digits``, ``max_decimal_places``,
``max_whole_digits``
The ``max_value`` and ``min_value`` error messages may contain
``%(limit_value)s``, which will be substituted by the appropriate limit.
The ``max_value`` and ``min_value`` error messages may contain
``%(limit_value)s``, which will be substituted by the appropriate limit.
Takes four optional arguments:
Takes four optional arguments:
.. attribute:: DecimalField.max_value
.. attribute:: DecimalField.min_value
.. attribute:: max_value
.. attribute:: min_value
These control the range of values permitted in the field, and should be
given as ``decimal.Decimal`` values.
These control the range of values permitted in the field, and should be
given as ``decimal.Decimal`` values.
.. attribute:: DecimalField.max_digits
.. attribute:: max_digits
The maximum number of digits (those before the decimal point plus those
after the decimal point, with leading zeros stripped) permitted in the
value.
The maximum number of digits (those before the decimal point plus those
after the decimal point, with leading zeros stripped) permitted in the
value.
.. attribute:: DecimalField.decimal_places
.. attribute:: decimal_places
The maximum number of decimal places permitted.
The maximum number of decimal places permitted.
``EmailField``
~~~~~~~~~~~~~~
@ -488,9 +488,9 @@ Takes four optional arguments:
moderately complex regular expression.
* Error message keys: ``required``, ``invalid``
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
given 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
given length.
.. versionchanged:: 1.2
The EmailField previously did not recognize email addresses as valid that
@ -510,20 +510,20 @@ given length.
* Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
``max_length``
Has two optional arguments for validation, ``max_length`` and
``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
content is empty.
Has two optional arguments for validation, ``max_length`` and
``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
content is empty.
To learn more about the ``UploadedFile`` object, see the :doc:`file uploads
documentation </topics/http/file-uploads>`.
To learn more about the ``UploadedFile`` object, see the :doc:`file uploads
documentation </topics/http/file-uploads>`.
When you use a ``FileField`` in a form, you must also remember to
:ref:`bind the file data to the form <binding-uploaded-files>`.
When you use a ``FileField`` in a form, you must also remember to
: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
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.
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
length and ``%(length)d`` will be replaced with the current filename length.
``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.
* Error message keys: ``required``, ``invalid_choice``
The field allows choosing from files inside a certain directory. It takes three
extra arguments; only ``path`` is required:
The field allows choosing from files inside a certain directory. It takes three
extra arguments; only ``path`` is required:
.. attribute:: FilePathField.path
.. attribute:: path
The absolute path to the directory whose contents you want listed. This
directory must exist.
The absolute path to the directory whose contents you want listed. This
directory must exist.
.. attribute:: FilePathField.recursive
.. attribute:: recursive
If ``False`` (the default) only the direct contents of ``path`` will be
offered as choices. If ``True``, the directory will be descended into
recursively and all descendants will be listed as choices.
If ``False`` (the default) only the direct contents of ``path`` will be
offered as choices. If ``True``, the directory will be descended into
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
will be allowed as choices.
A regular expression pattern; only files with names matching this expression
will be allowed as choices.
``FloatField``
~~~~~~~~~~~~~~
.. class:: FloatField(**kwargs)
* Default widget: ``TextInput``
* Empty value: ``None``
* Normalizes to: A Python float.
@ -566,8 +568,8 @@ extra arguments; only ``path`` is required:
* Error message keys: ``required``, ``invalid``, ``max_value``,
``min_value``
Takes two optional arguments for validation, ``max_value`` and ``min_value``.
These control the range of values permitted in the field.
Takes two optional arguments for validation, ``max_value`` and ``min_value``.
These control the range of values permitted in the field.
``ImageField``
~~~~~~~~~~~~~~
@ -583,10 +585,10 @@ These control the range of values permitted in the field.
* Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
``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
:ref:`bind the file data to the form <binding-uploaded-files>`.
When you use an ``ImageField`` on a form, you must also remember to
:ref:`bind the file data to the form <binding-uploaded-files>`.
.. _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``,
``min_value``
The ``max_value`` and ``min_value`` error messages may contain
``%(limit_value)s``, which will be substituted by the appropriate limit.
The ``max_value`` and ``min_value`` error messages may contain
``%(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:: IntegerField.min_value
.. attribute:: max_value
.. attribute:: min_value
These control the range of values permitted in the field.
@ -628,11 +630,11 @@ Takes two optional arguments for validation:
``GenericIPAddressField``
~~~~~~~~~~~~~~~~~~~~~~~~~
.. class:: GenericIPAddressField(**kwargs)
.. 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``
* 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.
* Error message keys: ``required``, ``invalid``
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
``::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
are converted to lowercase.
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
``::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
are converted to lowercase.
Takes two optional arguments:
Takes two optional arguments:
.. attribute:: GenericIPAddressField.protocol
.. attribute:: protocol
Limits valid inputs to the specified protocol.
Accepted values are ``both`` (default), ``IPv4``
or ``IPv6``. Matching is case insensitive.
Limits valid inputs to the specified protocol.
Accepted values are ``both`` (default), ``IPv4``
or ``IPv6``. Matching is case insensitive.
.. attribute:: GenericIPAddressField.unpack_ipv4
.. attribute:: unpack_ipv4
Unpacks IPv4 mapped addresses like ``::ffff::192.0.2.1``.
If this option is enabled that address would be unpacked to
``192.0.2.1``. Default is disabled. Can only be used
when ``protocol`` is set to ``'both'``.
Unpacks IPv4 mapped addresses like ``::ffff::192.0.2.1``.
If this option is enabled that address would be unpacked to
``192.0.2.1``. Default is disabled. Can only be used
when ``protocol`` is set to ``'both'``.
``MultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~
@ -674,20 +676,20 @@ Takes two optional arguments:
of choices.
* Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice.
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice.
Takes one extra required argument, ``choices``, as for ``ChoiceField``.
Takes one extra required argument, ``choices``, as for ``ChoiceField``.
``TypedMultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. class:: TypedMultipleChoiceField(**kwargs)
.. versionadded:: 1.3
Just like a :class:`MultipleChoiceField`, except :class:`TypedMultipleChoiceField`
takes two extra arguments, ``coerce`` and ``empty_value``.
.. class:: TypedMultipleChoiceField(**kwargs)
Just like a :class:`MultipleChoiceField`, except :class:`TypedMultipleChoiceField`
takes two extra arguments, ``coerce`` and ``empty_value``.
* Default widget: ``SelectMultiple``
* Empty value: Whatever you've given as ``empty_value``
@ -697,10 +699,10 @@ takes two extra arguments, ``coerce`` and ``empty_value``.
coerced.
* Error message keys: ``required``, ``invalid_choice``
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
replaced with the selected choice.
The ``invalid_choice`` error message may contain ``%(value)s``, which will be
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``
~~~~~~~~~~~~~~~~~~~~
@ -724,20 +726,20 @@ Takes two extra arguments, ``coerce`` and ``empty_value``, as for ``TypedChoiceF
expression.
* 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
expression object.
A regular expression specified either as a string or a compiled regular
expression object.
Also takes ``max_length`` and ``min_length``, which work just as they do for
``CharField``.
Also takes ``max_length`` and ``min_length``, which work just as they do for
``CharField``.
The optional argument ``error_message`` is also accepted for backwards
compatibility. The preferred way to provide an error message is to use the
``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
and the error message as the value.
The optional argument ``error_message`` is also accepted for backwards
compatibility. The preferred way to provide an error message is to use the
``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
and the error message as the value.
``SlugField``
~~~~~~~~~~~~~
@ -751,8 +753,8 @@ and the error message as the value.
underscores, and hyphens.
* Error messages: ``required``, ``invalid``
This field is intended for use in representing a model
:class:`~django.db.models.SlugField` in forms.
This field is intended for use in representing a model
:class:`~django.db.models.SlugField` in forms.
``TimeField``
~~~~~~~~~~~~~
@ -766,17 +768,17 @@ This field is intended for use in representing a model
formatted in a particular time format.
* 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
``datetime.time`` object.
A list of formats used to attempt to convert a string to a valid
``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', # '14:30'
'%H:%M:%S', # '14:30:59'
'%H:%M', # '14:30'
``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.
* Error message keys: ``required``, ``invalid``, ``invalid_link``
Takes the following optional arguments:
Takes the following optional arguments:
.. attribute:: URLField.max_length
.. attribute:: URLField.min_length
.. attribute:: max_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
``ValidationError`` if the page gives a 404. Defaults to ``False``.
If ``True``, the validator will attempt to load the given URL, raising
``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
Django 1.5. This deprecation also removes ``validator_user_agent``.
.. attribute:: 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
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``.
* 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 order in which they are provided).
The list of fields that should be used to validate the field's value (in
the order in which they are provided).
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean('test@example.com')
u'test@example.com'
>>> f.clean('longemailaddress@example.com')
Traceback (most recent call last):
...
ValidationError: [u'Ensure this value has at most 20 characters (it has 28).']
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean('test@example.com')
u'test@example.com'
>>> f.clean('longemailaddress@example.com')
Traceback (most recent call last):
...
ValidationError: [u'Ensure this value has at most 20 characters (it has 28).']
``MultiValueField``
~~~~~~~~~~~~~~~~~~~
@ -866,15 +867,15 @@ Takes one extra required argument:
:class:`SplitDateTimeField` is a subclass which combines a time field and
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
``clean`` is cleaned by the corresponding field in ``fields`` -- the first
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
values is "compressed" into a single value.
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
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
values is "compressed" into a single value.
``SplitDateTimeField``
~~~~~~~~~~~~~~~~~~~~~~
@ -889,23 +890,23 @@ Takes one extra required argument:
* Error message keys: ``required``, ``invalid``, ``invalid_date``,
``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
``datetime.date`` object.
A list of formats used to attempt to convert a string to a valid
``datetime.date`` object.
If no ``input_date_formats`` argument is provided, the default input formats
for ``DateField`` are used.
If no ``input_date_formats`` argument is provided, the default input formats
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
``datetime.time`` object.
A list of formats used to attempt to convert a string to a valid
``datetime.time`` object.
If no ``input_time_formats`` argument is provided, the default input formats
for ``TimeField`` are used.
If no ``input_time_formats`` argument is provided, the default input formats
for ``TimeField`` are used.
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.
* Error message keys: ``required``, ``invalid_choice``
Allows the selection of a single model object, suitable for
representing a foreign key. A single argument is required:
Allows the selection of a single model object, suitable for
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
field will be derived, and which will be used to validate the
user's selection.
A ``QuerySet`` of model objects from which the choices for the
field will be derived, and which will be used to validate the
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
empty choice at the top of the list. You can change the text of this
label (which is ``"---------"`` by default) with the ``empty_label``
attribute, or you can disable the empty label entirely by setting
``empty_label`` to ``None``::
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
label (which is ``"---------"`` by default) with the ``empty_label``
attribute, or you can disable the empty label entirely by setting
``empty_label`` to ``None``::
# A custom empty label
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
# A custom empty label
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
# No empty label
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
# No empty label
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
Note that if a ``ModelChoiceField`` is required and has a default
initial value, no empty choice is created (regardless of the value
of ``empty_label``).
Note that if a ``ModelChoiceField`` is required and has a default
initial value, no empty choice is created (regardless of the value
of ``empty_label``).
The ``__unicode__`` method of the model will be called to generate
string representations of the objects for use in the field's choices;
to provide customized representations, subclass ``ModelChoiceField``
and override ``label_from_instance``. This method will receive a model
object, and should return a string suitable for representing it. For
example::
The ``__unicode__`` method of the model will be called to generate
string representations of the objects for use in the field's choices;
to provide customized representations, subclass ``ModelChoiceField``
and override ``label_from_instance``. This method will receive a model
object, and should return a string suitable for representing it. For
example::
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "My Object #%i" % obj.id
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "My Object #%i" % obj.id
``ModelMultipleChoiceField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -983,16 +984,16 @@ example::
* Error message keys: ``required``, ``list``, ``invalid_choice``,
``invalid_pk_value``
Allows the selection of one or more model objects, suitable for
representing a many-to-many relation. As with :class:`ModelChoiceField`,
you can use ``label_from_instance`` to customize the object
representations, and ``queryset`` is a required parameter:
Allows the selection of one or more model objects, suitable for
representing a many-to-many relation. As with :class:`ModelChoiceField`,
you can use ``label_from_instance`` to customize the object
representations, and ``queryset`` is a required parameter:
.. attribute:: ModelMultipleChoiceField.queryset
.. attribute:: queryset
A ``QuerySet`` of model objects from which the choices for the
field will be derived, and which will be used to validate the
user's selection.
A ``QuerySet`` of model objects from which the choices for the
field will be derived, and which will be used to validate the
user's selection.
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
overridden:
* The ``to_python()`` method on a Field is the first step in every
validation. It coerces the value to correct datatype and raises
``ValidationError`` if that is not possible. This method accepts the raw
value from the widget and returns the converted value. For example, a
FloatField will turn the data into a Python ``float`` or raise a
``ValidationError``.
* The ``to_python()`` method on a Field is the first step in every
validation. It coerces the value to correct datatype and raises
``ValidationError`` if that is not possible. This method accepts the raw
value from the widget and returns the converted value. For example, a
FloatField will turn the data into a Python ``float`` or raise a
``ValidationError``.
* The ``validate()`` method on a Field handles field-specific validation
that is not suitable for a validator, It takes a value that has been
coerced to correct datatype and raises ``ValidationError`` on any error.
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
want to put in a validator.
* The ``validate()`` method on a Field handles field-specific validation
that is not suitable for a validator, It takes a value that has been
coerced to correct datatype and raises ``ValidationError`` on any error.
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
want to put in a validator.
* The ``run_validators()`` method on a Field runs all of the field's
validators and aggregates all the errors into a single
``ValidationError``. You shouldn't need to override this method.
* The ``run_validators()`` method on a Field runs all of the field's
validators and aggregates all the errors into a single
``ValidationError``. You shouldn't need to override this method.
* The ``clean()`` method on a Field subclass. This is responsible for
running ``to_python``, ``validate`` and ``run_validators`` in the correct
order and propagating their errors. If, at any time, any of the methods
raise ``ValidationError``, the validation stops and that error is raised.
This method returns the clean data, which is then inserted into the
``cleaned_data`` dictionary of the form.
* The ``clean()`` method on a Field subclass. This is responsible for
running ``to_python``, ``validate`` and ``run_validators`` in the correct
order and propagating their errors. If, at any time, any of the methods
raise ``ValidationError``, the validation stops and that error is raised.
This method returns the clean data, which is then inserted into the
``cleaned_data`` dictionary of the form.
* The ``clean_<fieldname>()`` method in a form subclass -- where
``<fieldname>`` is replaced with the name of the form field attribute.
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
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
at this point, not the original string submitted in the form (it will be
in ``cleaned_data`` because the general field ``clean()`` method, above,
has already cleaned the data once).
* The ``clean_<fieldname>()`` method in a form subclass -- where
``<fieldname>`` is replaced with the name of the form field attribute.
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
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
at this point, not the original string submitted in the form (it will be
in ``cleaned_data`` because the general field ``clean()`` method, above,
has already cleaned the data once).
For example, if you wanted to validate that the contents of a
``CharField`` called ``serialnumber`` was unique,
``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
formfield-specific piece of validation and, possibly,
cleaning/normalizing the data.
For example, if you wanted to validate that the contents of a
``CharField`` called ``serialnumber`` was unique,
``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
formfield-specific piece of validation and, possibly,
cleaning/normalizing the data.
Just like the general field ``clean()`` method, above, this method
should return the cleaned data, regardless of whether it changed
anything or not.
Just like the general field ``clean()`` method, above, this method
should return the cleaned data, regardless of whether it changed
anything or not.
* The Form subclass's ``clean()`` method. This method can perform
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``
is supplied, field ``B`` must contain a valid email address and the
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
cleaned data if you override this method (by default, ``Form.clean()``
just returns ``self.cleaned_data``).
* The Form subclass's ``clean()`` method. This method can perform
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``
is supplied, field ``B`` must contain a valid email address and the
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
cleaned data if you override this method (by default, ``Form.clean()``
just returns ``self.cleaned_data``).
Note that any errors raised by your ``Form.clean()`` override will not
be associated with any field in particular. They go into a special
"field" (called ``__all__``), which you can access via the
``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`` attribute on the form, which is `described later`_.
Note that any errors raised by your ``Form.clean()`` override will not
be associated with any field in particular. They go into a special
"field" (called ``__all__``), which you can access via the
``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`` attribute on the form, which is `described later`_.
Also note that there are special considerations when overriding
the ``clean()`` method of a ``ModelForm`` subclass. (see the
:ref:`ModelForm documentation
<overriding-modelform-clean-method>` for more information)
Also note that there are special considerations when overriding
the ``clean()`` method of a ``ModelForm`` subclass. (see the
:ref:`ModelForm documentation
<overriding-modelform-clean-method>` for more information)
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

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
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()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
This would specify a form with a comment that uses a larger :class:`Textarea`
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
widget on the field. In the following example, the
: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
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
from django.forms.extras.widgets import SelectDateWidget
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'))
FAVORITE_COLORS_CHOICES = (('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'))
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'))
FAVORITE_COLORS_CHOICES = (('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'))
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)
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
are available and which arguments they accept.
@ -78,21 +74,19 @@ buttons.
:class:`Select` widgets are used by default on :class:`ChoiceField` fields. The
choices displayed on the widget are inherited from the :class:`ChoiceField` and
changing :attr:`ChoiceField.choices` will update :attr:`Select.choices`. For
example:
example::
.. code-block:: python
>>> from django import forms
>>> CHOICES = (('1', 'First',), ('2', 'Second',)))
>>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
>>> choice_field.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices = ()
>>> choice_field.choices = (('1', 'First and only',),)
>>> choice_field.widget.choices
[('1', 'First and only')]
>>> from django import forms
>>> CHOICES = (('1', 'First',), ('2', 'Second',)))
>>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
>>> choice_field.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices = ()
>>> choice_field.choices = (('1', 'First and only',),)
>>> choice_field.widget.choices
[('1', 'First and only')]
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
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()
url = forms.URLField()
comment = forms.CharField()
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField()
This form will include three default :class:`TextInput` widgets, with default
rendering -- no CSS class, no extra attributes. This means that the input boxes
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>
provided for each widget will be rendered exactly the same::
>>> 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
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
:attr:`Widget.attrs` argument when creating the widget:
For example:
For example::
.. code-block:: python
class CommentForm(forms.Form):
name = forms.CharField(
widget=forms.TextInput(attrs={'class':'special'}))
url = forms.URLField()
comment = forms.CharField(
widget=forms.TextInput(attrs={'size':'40'}))
class CommentForm(forms.Form):
name = forms.CharField(
widget=forms.TextInput(attrs={'class':'special'}))
url = forms.URLField()
comment = forms.CharField(
widget=forms.TextInput(attrs={'size':'40'}))
Django will then include the extra attributes in the rendered output:
.. code-block:: python
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></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>
>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></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:
@ -411,9 +396,7 @@ commonly used groups of widgets:
:class:`MultiWidget`'s subclasses must implement. This method takes a
single "compressed" value and returns a ``list``. An example of this is how
:class:`SplitDateTimeWidget` turns a :class:`datetime` value into a list
with date and time split into two seperate values:
.. code-block:: python
with date and time split into two seperate values::
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:
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
setting, which should be a list of strings.
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
setting, which should be a list of strings.
* Performs URL rewriting based on the :setting:`APPEND_SLASH` and
:setting:`PREPEND_WWW` settings.
* Performs URL rewriting based on the :setting:`APPEND_SLASH` and
:setting:`PREPEND_WWW` settings.
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
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,
the initial URL is processed as usual.
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
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,
the initial URL is processed as usual.
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
valid pattern for ``foo.com/bar/``.
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
valid pattern for ``foo.com/bar/``.
If :setting:`PREPEND_WWW` is ``True``, URLs that lack a leading "www."
will be redirected to the same URL with 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."
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
``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
normalize URLs.
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
``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
normalize URLs.
* Sends broken link notification emails to :setting:`MANAGERS` if
:setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``.
* Sends broken link notification emails to :setting:`MANAGERS` if
:setting:`SEND_BROKEN_LINK_EMAILS` is set to ``True``.
* Handles ETags based on the :setting:`USE_ETAGS` setting. If
: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
sending ``Not Modified`` responses, if appropriate.
* Handles ETags based on the :setting:`USE_ETAGS` setting. If
: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
sending ``Not Modified`` responses, if appropriate.
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
passed are:
====================== ===============================================
Argument Description
====================== ===============================================
``instance`` An instance of the model where the
``FileField`` is defined. More specifically,
this is the particular instance where the
current file is being attached.
====================== ===============================================
Argument Description
====================== ===============================================
``instance`` An instance of the model where the
``FileField`` is defined. More specifically,
this is the particular instance where the
current file is being attached.
In most cases, this object will not have been
saved to the database yet, so if it uses the
default ``AutoField``, *it might not yet have a
value for its primary key field*.
In most cases, this object will not have been
saved to the database yet, so if it uses the
default ``AutoField``, *it might not yet have a
value for its primary key field*.
``filename`` The filename that was originally given to the
file. This may or may not be taken into account
when determining the final destination path.
====================== ===============================================
``filename`` The filename that was originally given to the
file. This may or may not be taken into account
when determining the final destination path.
====================== ===============================================
Also has one optional argument:
@ -541,22 +541,22 @@ widget).
Using a :class:`FileField` or an :class:`ImageField` (see below) in a model
takes a few steps:
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.
(For performance, these files are not stored in the database.) 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 account.
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.
(For performance, these files are not stored in the database.) 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 account.
2. Add the :class:`FileField` or :class:`ImageField` to your model, making
sure to define the :attr:`~FileField.upload_to` option to tell Django
to which subdirectory of :setting:`MEDIA_ROOT` it should upload files.
2. Add the :class:`FileField` or :class:`ImageField` to your model, making
sure to define the :attr:`~FileField.upload_to` option to tell Django
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
(relative to :setting:`MEDIA_ROOT`). You'll most likely want to use the
convenience :attr:`~django.core.files.File.url` function provided by
Django. For example, if your :class:`ImageField` is called ``mug_shot``,
you can get the absolute path to your image in a template with
``{{ object.mug_shot.url }}``.
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
convenience :attr:`~django.core.files.File.url` function provided by
Django. For example, if your :class:`ImageField` is called ``mug_shot``,
you can get the absolute path to your image in a template with
``{{ object.mug_shot.url }}``.
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'``

View File

@ -34,9 +34,9 @@ Validating objects
There are three steps involved in validating a model:
1. Validate the model fields
2. Validate the model as a whole
3. Validate the field uniqueness
1. Validate the model fields
2. Validate the model as a whole
3. Validate the field uniqueness
All three steps are performed when you call a model's
:meth:`~Model.full_clean()` method.
@ -211,43 +211,43 @@ What happens when you save?
When you save an object, Django performs the following steps:
1. **Emit a pre-save signal.** The :doc:`signal </ref/signals>`
:attr:`django.db.models.signals.pre_save` is sent, allowing any
functions listening for that signal to take some customized
action.
1. **Emit a pre-save signal.** The :doc:`signal </ref/signals>`
:attr:`django.db.models.signals.pre_save` is sent, allowing any
functions listening for that signal to take some customized
action.
2. **Pre-process the data.** Each field on the object is asked to
perform any automated data modification that the field may need
to perform.
2. **Pre-process the data.** Each field on the object is asked to
perform any automated data modification that the field may need
to perform.
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
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
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
"special behavior.")
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
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
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
"special behavior.")
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.
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.
Most fields require *no* data preparation. Simple data types, such as
integers and strings, are 'ready to write' as a Python object. However,
more complex data types often require some modification.
Most fields require *no* data preparation. Simple data types, such as
integers and strings, are 'ready to write' as a Python object. However,
more complex data types often require some modification.
For example, :class:`~django.db.models.DateField` fields use a Python
``datetime`` object to store data. Databases don't store ``datetime``
objects, so the field value must be converted into an ISO-compliant date
string for insertion into the database.
For example, :class:`~django.db.models.DateField` fields use a Python
``datetime`` object to store data. Databases don't store ``datetime``
objects, so the field value must be converted into an ISO-compliant date
string for insertion into the database.
4. **Insert the data into the database.** The pre-processed, prepared
data is then composed into an SQL statement for insertion into the
database.
4. **Insert the data into the database.** The pre-processed, prepared
data is then composed into an SQL statement for insertion into the
database.
5. **Emit a post-save signal.** The signal
:attr:`django.db.models.signals.post_save` is sent, allowing
any functions listening for that signal to take some customized
action.
5. **Emit a post-save signal.** The signal
:attr:`django.db.models.signals.post_save` is sent, allowing
any functions listening for that signal to take some customized
action.
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
follows this algorithm:
* 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
executes a ``SELECT`` query to determine whether a record with the given
primary key already exists.
* If the record with the given primary key does already exist, Django
executes an ``UPDATE`` query.
* 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``.
* 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
executes a ``SELECT`` query to determine whether a record with the given
primary key already exists.
* If the record with the given primary key does already exist, Django
executes an ``UPDATE`` query.
* 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``.
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

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
model handling are exactly the same as normal. This includes
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
recommended to specify all the columns from the database table you
are modeling when using unmanaged models.
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
recommended to specify all the columns from the database table you
are modeling when using unmanaged models.
2. If a model with ``managed=False`` contains a
:class:`~django.db.models.ManyToManyField` that points to another
unmanaged model, then the intermediate table for the many-to-many
join will also not be created. However, the intermediary table
between one managed and one unmanaged model *will* be created.
2. If a model with ``managed=False`` contains a
:class:`~django.db.models.ManyToManyField` that points to another
unmanaged model, then the intermediate table for the many-to-many
join will also not be created. However, the intermediary table
between one managed and one unmanaged model *will* be created.
If you need to change this default behavior, create the intermediary
table as an explicit model (with ``managed`` set as needed) and use
the :attr:`ManyToManyField.through` attribute to make the relation
use your custom model.
If you need to change this default behavior, create the intermediary
table as an explicit model (with ``managed`` set as needed) and use
the :attr:`ManyToManyField.through` attribute to make the relation
use your custom model.
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.

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
related context. This happens in two cases:
* The "other side" of a :class:`~django.db.models.ForeignKey` relation.
That is::
* The "other side" of a :class:`~django.db.models.ForeignKey` relation.
That is::
class Reporter(models.Model):
...
class Reporter(models.Model):
...
class Article(models.Model):
reporter = models.ForeignKey(Reporter)
class Article(models.Model):
reporter = models.ForeignKey(Reporter)
In the above example, the methods below will be available on
the manager ``reporter.article_set``.
In the above example, the methods below will be available on
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):
toppings = models.ManyToManyField(Topping)
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
In this example, the methods below will be available both on
``topping.pizza_set`` and on ``pizza.toppings``.
In this example, the methods below will be available both on
``topping.pizza_set`` and on ``pizza.toppings``.
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
examples:
* ``CONTENT_LENGTH`` -- the length of the request body (as a string).
* ``CONTENT_TYPE`` -- the MIME type of the request body.
* ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response.
* ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response.
* ``HTTP_HOST`` -- The HTTP Host header sent by the client.
* ``HTTP_REFERER`` -- The referring page, if any.
* ``HTTP_USER_AGENT`` -- The client's user-agent string.
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
* ``REMOTE_ADDR`` -- The IP address of the client.
* ``REMOTE_HOST`` -- The hostname of the client.
* ``REMOTE_USER`` -- The user authenticated by the Web server, if any.
* ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
* ``SERVER_NAME`` -- The hostname of the server.
* ``SERVER_PORT`` -- The port of the server (as a string).
* ``CONTENT_LENGTH`` -- the length of the request body (as a string).
* ``CONTENT_TYPE`` -- the MIME type of the request body.
* ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response.
* ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response.
* ``HTTP_HOST`` -- The HTTP Host header sent by the client.
* ``HTTP_REFERER`` -- The referring page, if any.
* ``HTTP_USER_AGENT`` -- The client's user-agent string.
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
* ``REMOTE_ADDR`` -- The IP address of the client.
* ``REMOTE_HOST`` -- The hostname of the client.
* ``REMOTE_USER`` -- The user authenticated by the Web server, if any.
* ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
* ``SERVER_NAME`` -- The hostname of the server.
* ``SERVER_PORT`` -- The port of the server (as a string).
With the exception of ``CONTENT_LENGTH`` and ``CONTENT_TYPE``, as given
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
hard-coded strings. If you use this technique, follow these guidelines:
* The iterator should return strings.
* 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
object. Doing so will raise ``Exception``.
* The iterator should return strings.
* 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
object. Doing so will raise ``Exception``.
Setting headers
~~~~~~~~~~~~~~~
@ -649,27 +649,27 @@ Methods
Sets a cookie. The parameters are the same as in the :class:`Cookie.Morsel`
object in the Python standard library.
* ``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.
If ``expires`` is not specified, it will be calculated.
* ``expires`` should either be a string in the format
``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
will be calculated.
* Use ``domain`` if you want to set a cross-domain cookie. For example,
``domain=".lawrence.com"`` will set a cookie that is readable by
the domains www.lawrence.com, blogs.lawrence.com and
calendars.lawrence.com. Otherwise, a cookie will only be readable by
the domain that set it.
* Use ``httponly=True`` if you want to prevent client-side
JavaScript from having access to the cookie.
* ``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.
If ``expires`` is not specified, it will be calculated.
* ``expires`` should either be a string in the format
``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
will be calculated.
* Use ``domain`` if you want to set a cross-domain cookie. For example,
``domain=".lawrence.com"`` will set a cookie that is readable by
the domains www.lawrence.com, blogs.lawrence.com and
calendars.lawrence.com. Otherwise, a cookie will only be readable by
the domain that set it.
* Use ``httponly=True`` if you want to prevent client-side
JavaScript from having access to the cookie.
HTTPOnly_ is a flag included in a Set-Cookie HTTP response
header. It is not part of the :rfc:`2109` standard for cookies,
and it isn't honored consistently by all browsers. However,
when it is honored, it can be a useful way to mitigate the
risk of client side script accessing the protected cookie
data.
HTTPOnly_ is a flag included in a Set-Cookie HTTP response
header. It is not part of the :rfc:`2109` standard for cookies,
and it isn't honored consistently by all browsers. However,
when it is honored, it can be a useful way to mitigate the
risk of client side script accessing the protected cookie
data.
.. _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:
* ``'django.core.cache.backends.db.DatabaseCache'``
* ``'django.core.cache.backends.dummy.DummyCache'``
* ``'django.core.cache.backends.filebased.FileBasedCache'``
* ``'django.core.cache.backends.locmem.LocMemCache'``
* ``'django.core.cache.backends.memcached.MemcachedCache'``
* ``'django.core.cache.backends.memcached.PyLibMCCache'``
* ``'django.core.cache.backends.db.DatabaseCache'``
* ``'django.core.cache.backends.dummy.DummyCache'``
* ``'django.core.cache.backends.filebased.FileBasedCache'``
* ``'django.core.cache.backends.locmem.LocMemCache'``
* ``'django.core.cache.backends.memcached.MemcachedCache'``
* ``'django.core.cache.backends.memcached.PyLibMCCache'``
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
@ -412,10 +412,10 @@ Default: ``''`` (Empty string)
The database backend to use. The built-in database backends are:
* ``'django.db.backends.postgresql_psycopg2'``
* ``'django.db.backends.mysql'``
* ``'django.db.backends.sqlite3'``
* ``'django.db.backends.oracle'``
* ``'django.db.backends.postgresql_psycopg2'``
* ``'django.db.backends.mysql'``
* ``'django.db.backends.sqlite3'``
* ``'django.db.backends.oracle'``
You can use a database backend that doesn't ship with Django by setting
``ENGINE`` to a fully-qualified path (i.e.
@ -1165,9 +1165,9 @@ Default: ``()`` (Empty tuple)
A tuple of IP addresses, as strings, that:
* See debug comments, when :setting:`DEBUG` is ``True``
* Receive X headers if the ``XViewMiddleware`` is installed (see
:doc:`/topics/http/middleware`)
* See debug comments, when :setting:`DEBUG` is ``True``
* Receive X headers if the ``XViewMiddleware`` is installed (see
:doc:`/topics/http/middleware`)
.. setting:: LANGUAGE_CODE
@ -1389,11 +1389,11 @@ MESSAGE_TAGS
Default::
{messages.DEBUG: 'debug',
messages.INFO: 'info',
messages.SUCCESS: 'success',
messages.WARNING: 'warning',
messages.ERROR: 'error',}
{messages.DEBUG: 'debug',
messages.INFO: 'info',
messages.SUCCESS: 'success',
messages.WARNING: 'warning',
messages.ERROR: 'error',}
Sets the mapping of message levels to message tags. See the
: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:
* ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'``
* ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'``
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
following conditions:
* If you're using the manual configuration option as described in
:ref:`manually configuring settings
<settings-without-django-settings-module>`, or
* If you're using the manual configuration option as described in
:ref:`manually configuring settings
<settings-without-django-settings-module>`, or
* If you specify ``TIME_ZONE = None``. This will cause Django to fall
back to using the system timezone.
* If you specify ``TIME_ZONE = None``. This will cause Django to fall
back to using the system timezone.
If Django doesn't set the ``TZ`` environment variable, it's up to you
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
:meth:`~django.db.models.Model.__init__`:.
For example, the :doc:`tutorial </intro/tutorial01>` has this line:
.. code-block:: python
For example, the :doc:`tutorial </intro/tutorial01>` has this line::
p = Poll(question="What's up?", pub_date=datetime.now())
The arguments sent to a :data:`pre_init` handler would be:
========== ===============================================================
Argument Value
========== ===============================================================
``sender`` ``Poll`` (the class itself)
========== ===============================================================
Argument Value
========== ===============================================================
``sender`` ``Poll`` (the class itself)
``args`` ``[]`` (an empty list because there were no positional
arguments passed to ``__init__``.)
``args`` ``[]`` (an empty list because there were no positional
arguments passed to ``__init__``.)
``kwargs`` ``{'question': "What's up?", 'pub_date': datetime.now()}``
========== ===============================================================
``kwargs`` ``{'question': "What's up?", 'pub_date': datetime.now()}``
========== ===============================================================
post_init
---------
@ -269,12 +267,11 @@ Arguments sent with this signal:
The database alias being used.
For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled
like this:
.. code-block:: python
like this::
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
# ...
@ -282,62 +279,58 @@ like this:
If we would do something like this:
.. code-block:: python
>>> p = Pizza.object.create(...)
>>> t = Topping.objects.create(...)
>>> p.toppings.add(t)
the arguments sent to a :data:`m2m_changed` handler would be:
============== ============================================================
Argument Value
============== ============================================================
``sender`` ``Pizza.toppings.through`` (the intermediate m2m class)
============== ============================================================
Argument Value
============== ============================================================
``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`,
so this call modifies the forward relation)
``reverse`` ``False`` (``Pizza`` contains the :class:`ManyToManyField`,
so this call modifies the forward relation)
``model`` ``Topping`` (the class of the objects added to the
``Pizza``)
``model`` ``Topping`` (the class of the objects added to the
``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:
.. code-block:: python
And if we would then do something like this::
>>> t.pizza_set.remove(p)
the arguments sent to a :data:`m2m_changed` handler would be:
============== ============================================================
Argument Value
============== ============================================================
``sender`` ``Pizza.toppings.through`` (the intermediate m2m class)
============== ============================================================
Argument Value
============== ============================================================
``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`,
so this call modifies the reverse relation)
``reverse`` ``True`` (``Pizza`` contains the :class:`ManyToManyField`,
so this call modifies the reverse relation)
``model`` ``Pizza`` (the class of the objects removed from the
``Topping``)
``model`` ``Pizza`` (the class of the objects removed from the
``Topping``)
``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the
relation)
``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the
relation)
``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================
``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================
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
rendered:
* When the TemplateResponse instance is explicitly rendered, using
the :meth:`SimpleTemplateResponse.render()` method.
* When the TemplateResponse instance is explicitly rendered, using
the :meth:`SimpleTemplateResponse.render()` method.
* When the content of the response is explicitly set by assigning
:attr:`response.content`.
* When the content of the response is explicitly set by assigning
:attr:`response.content`.
* After passing through template response middleware, but before
passing through response middleware.
* After passing through template response middleware, but before
passing through response middleware.
A TemplateResponse can only be rendered once. The first call to
: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:
* First, you compile the raw template code into a ``Template`` object.
* Then, you call the ``render()`` method of the ``Template`` object with a
given context.
* First, you compile the raw template code into a ``Template`` object.
* Then, you call the ``render()`` method of the ``Template`` object with a
given context.
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)
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
to help :ref:`resolve namespaced URLs<topics-http-reversing-url-namespaces>`.
If you're not using namespaced URLs, you can ignore this argument.
* The name of the current application. This application name is used
to help :ref:`resolve namespaced URLs<topics-http-reversing-url-namespaces>`.
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
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
dot in a variable name, it tries the following lookups, in this order:
* Dictionary lookup. Example: ``foo["bar"]``
* Attribute lookup. Example: ``foo.bar``
* List-index lookup. Example: ``foo[bar]``
* Dictionary lookup. Example: ``foo["bar"]``
* Attribute lookup. Example: ``foo.bar``
* List-index lookup. Example: ``foo[bar]``
The template system uses the first lookup type that works. It's short-circuit
logic. Here are a few examples::
@ -161,69 +161,69 @@ it. Example::
Callable variables are slightly more complex than variables which only require
straight lookups. Here are some things to keep in mind:
* If the variable raises an exception when called, the exception will be
propagated, unless the exception has an attribute
``silent_variable_failure`` whose value is ``True``. If the exception
*does* have a ``silent_variable_failure`` attribute whose value is
``True``, the variable will render as an empty string. Example::
* If the variable raises an exception when called, the exception will be
propagated, unless the exception has an attribute
``silent_variable_failure`` whose value is ``True``. If the exception
*does* have a ``silent_variable_failure`` attribute whose value is
``True``, the variable will render as an empty string. Example::
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
... def first_name(self):
... raise AssertionError("foo")
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
...
AssertionError: foo
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
... def first_name(self):
... raise AssertionError("foo")
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
...
AssertionError: foo
>>> class SilentAssertionError(Exception):
... silent_variable_failure = True
>>> class PersonClass4:
... def first_name(self):
... raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
"My name is ."
>>> class SilentAssertionError(Exception):
... silent_variable_failure = True
>>> class PersonClass4:
... def first_name(self):
... raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
"My name is ."
Note that :exc:`django.core.exceptions.ObjectDoesNotExist`, which is the
base class for all Django database API ``DoesNotExist`` exceptions, has
``silent_variable_failure = True``. So if you're using Django templates
with Django model objects, any ``DoesNotExist`` exception will fail
silently.
Note that :exc:`django.core.exceptions.ObjectDoesNotExist`, which is the
base class for all Django database API ``DoesNotExist`` exceptions, has
``silent_variable_failure = True``. So if you're using Django templates
with Django model objects, any ``DoesNotExist`` exception will fail
silently.
* A variable can only be called if it has no required arguments. Otherwise,
the system will return an empty string.
* A variable can only be called if it has no required arguments. Otherwise,
the system will return an empty string.
* 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
to access them.
* 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
to access them.
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
something like this::
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
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
variable. The template system won't call a variable if it has
``alters_data=True`` set, and will instead replace the variable with
:setting:`TEMPLATE_STRING_IF_INVALID`, unconditionally. The
dynamically-generated :meth:`~django.db.models.Model.delete` and
:meth:`~django.db.models.Model.save` methods on Django model objects get
``alters_data=True`` automatically. Example::
To prevent this, set an ``alters_data`` attribute on the callable
variable. The template system won't call a variable if it has
``alters_data=True`` set, and will instead replace the variable with
:setting:`TEMPLATE_STRING_IF_INVALID`, unconditionally. The
dynamically-generated :meth:`~django.db.models.Model.delete` and
:meth:`~django.db.models.Model.save` methods on Django model objects get
``alters_data=True`` automatically. Example::
def sensitive_function(self):
self.database_record.delete()
sensitive_function.alters_data = True
def sensitive_function(self):
self.database_record.delete()
sensitive_function.alters_data = True
* .. versionadded:: 1.4
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
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
if your variable is not callable (allowing you to access attributes of
the callable, for example).
* .. versionadded:: 1.4
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
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
if your variable is not callable (allowing you to access attributes of
the callable, for example).
.. _invalid-template-variables:
@ -427,13 +427,13 @@ django.contrib.auth.context_processors.auth
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain these three variables:
* ``user`` -- An ``auth.User`` instance representing the currently
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
logged in).
* ``user`` -- An ``auth.User`` instance representing the currently
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
logged in).
* ``perms`` -- An instance of
``django.contrib.auth.context_processors.PermWrapper``, representing the
permissions that the currently logged-in user has.
* ``perms`` -- An instance of
``django.contrib.auth.context_processors.PermWrapper``, representing the
permissions that the currently logged-in user has.
.. versionchanged:: 1.2
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
(``request.META['REMOTE_ADDR']``) is in the :setting:`INTERNAL_IPS` setting:
* ``debug`` -- ``True``. You can use this in templates to test whether
you're in :setting:`DEBUG` mode.
* ``sql_queries`` -- A list of ``{'sql': ..., 'time': ...}`` dictionaries,
representing every SQL query that has happened so far during the request
and how long it took. The list is in order by query.
* ``debug`` -- ``True``. You can use this in templates to test whether
you're in :setting:`DEBUG` mode.
* ``sql_queries`` -- A list of ``{'sql': ..., 'time': ...}`` dictionaries,
representing every SQL query that has happened so far during the request
and how long it took. The list is in order by query.
django.core.context_processors.i18n
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -464,9 +464,9 @@ django.core.context_processors.i18n
If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
``RequestContext`` will contain these two variables:
* ``LANGUAGES`` -- The value of the :setting:`LANGUAGES` setting.
* ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise,
the value of the :setting:`LANGUAGE_CODE` setting.
* ``LANGUAGES`` -- The value of the :setting:`LANGUAGES` setting.
* ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise,
the value of the :setting:`LANGUAGE_CODE` setting.
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
``RequestContext`` will contain a single additional variable:
* ``messages`` -- A list of messages (as strings) that have been set
via the user model (using ``user.message_set.create``) or through
the :doc:`messages framework </ref/contrib/messages>`.
* ``messages`` -- A list of messages (as strings) that have been set
via the user model (using ``user.message_set.create``) or through
the :doc:`messages framework </ref/contrib/messages>`.
.. versionadded:: 1.2
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,
in order:
* ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html``
* ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html``
If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``,
here's what Django will look for:
* ``/home/html/templates/lawrence.com/story_253_detail.html``
* ``/home/html/templates/default/story_253_detail.html``
* ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html``
* ``/home/html/templates/lawrence.com/story_253_detail.html``
* ``/home/html/templates/default/story_253_detail.html``
* ``/home/html/templates/lawrence.com/story_detail.html``
* ``/home/html/templates/default/story_detail.html``
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
``get_template()`` call will attempt to load the following templates:
* ``/home/html/templates/lawrence.com/news/story_detail.html``
* ``/home/html/templates/default/news/story_detail.html``
* ``/home/html/templates/lawrence.com/news/story_detail.html``
* ``/home/html/templates/default/news/story_detail.html``
.. _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
directories, in this order:
* ``/path/to/myproject/polls/templates/foo.html``
* ``/path/to/myproject/music/templates/foo.html``
* ``/path/to/myproject/polls/templates/foo.html``
* ``/path/to/myproject/music/templates/foo.html``
Note that the loader performs an optimization when it is first imported: It
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
the first template in the list that exists) -- and two optional arguments:
dictionary
A dictionary to be used as variables and values for the
template's context. This can also be passed as the second
positional argument.
dictionary
A dictionary to be used as variables and values for the
template's context. This can also be passed as the second
positional argument.
context_instance
An instance of ``Context`` or a subclass (e.g., an instance of
``RequestContext``) to use as the template's context. This can
also be passed as the third positional argument.
context_instance
An instance of ``Context`` or a subclass (e.g., an instance of
``RequestContext``) to use as the template's context. This can
also be passed as the third positional argument.
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`

View File

@ -201,13 +201,13 @@ Signals that this template extends a parent template.
This tag can be used in two ways:
* ``{% extends "base.html" %}`` (with quotes) uses the literal value
``"base.html"`` as the name of the parent template to extend.
* ``{% extends "base.html" %}`` (with quotes) uses the literal value
``"base.html"`` as the name of the parent template to extend.
* ``{% extends variable %}`` uses the value of ``variable``. If the variable
evaluates to a string, Django will use that string as the name of the
parent template. If the variable evaluates to a ``Template`` object,
Django will use that object as the parent template.
* ``{% extends variable %}`` uses the value of ``variable``. If the variable
evaluates to a string, Django will use that string as the name of the
parent template. If the variable evaluates to a ``Template`` object,
Django will use that object as the parent template.
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:
========================== ===============================================
Variable Description
========================== ===============================================
``forloop.counter`` The current iteration of the loop (1-indexed)
``forloop.counter0`` The current iteration of the loop (0-indexed)
``forloop.revcounter`` The number of iterations from the end of the
loop (1-indexed)
``forloop.revcounter0`` The number of iterations from the end of the
loop (0-indexed)
``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.parentloop`` For nested loops, this is the loop "above" the
current one
========================== ===============================================
========================== ===============================================
Variable Description
========================== ===============================================
``forloop.counter`` The current iteration of the loop (1-indexed)
``forloop.counter0`` The current iteration of the loop (0-indexed)
``forloop.revcounter`` The number of iterations from the end of the
loop (1-indexed)
``forloop.revcounter0`` The number of iterations from the end of the
loop (0-indexed)
``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.parentloop`` For nested loops, this is the loop "above" the
current one
========================== ===============================================
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
operators, from lowest to highest, is as follows:
* ``or``
* ``and``
* ``not``
* ``in``
* ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``
* ``or``
* ``and``
* ``not``
* ``in``
* ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``
(This follows Python exactly). So, for example, the following complex
:ttag:`if` tag:
@ -660,14 +660,14 @@ the variable ``template_name``::
An included template is rendered with the context of the template that's
including it. This example produces the output ``"Hello, John"``:
* Context: variable ``person`` is set to ``"john"``.
* Template::
* Context: variable ``person`` is set to ``"john"``.
* 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
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,
like this:
* Male:
* George Bush
* Bill Clinton
* Female:
* Margaret Thatcher
* Condoleezza Rice
* Unknown:
* Pat Smith
* Male:
* George Bush
* Bill Clinton
* Female:
* Margaret Thatcher
* Condoleezza Rice
* Unknown:
* Pat Smith
You can use the ``{% regroup %}`` tag to group the list of people by gender.
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
**group objects**. Each group object has two attributes:
* ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
"Female").
* ``list`` -- a list of all items in this group (e.g., a list of all people
with gender='Male').
* ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
"Female").
* ``list`` -- a list of all items in this group (e.g., a list of all people
with gender='Male').
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.
@ -830,16 +830,16 @@ grouped together):
With this input for ``people``, the example ``{% regroup %}`` template code
above would result in the following output:
* Male:
* Bill Clinton
* Unknown:
* Pat Smith
* Female:
* Margaret Thatcher
* Male:
* George Bush
* Female:
* Condoleezza Rice
* Male:
* Bill Clinton
* Unknown:
* Pat Smith
* Female:
* Margaret Thatcher
* Male:
* George Bush
* Female:
* Condoleezza Rice
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.
@ -959,18 +959,18 @@ bits used in template tags, you must use the ``{% templatetag %}`` tag.
The argument tells which template bit to output:
================== =======
Argument Outputs
================== =======
``openblock`` ``{%``
``closeblock`` ``%}``
``openvariable`` ``{{``
``closevariable`` ``}}``
``openbrace`` ``{``
``closebrace`` ``}``
``opencomment`` ``{#``
``closecomment`` ``#}``
================== =======
================== =======
Argument Outputs
================== =======
``openblock`` ``{%``
``closeblock`` ``%}``
``openvariable`` ``{{``
``closevariable`` ``}}``
``openbrace`` ``{``
``closebrace`` ``}``
``opencomment`` ``{#``
``closecomment`` ``#}``
================== =======
.. templatetag:: url
@ -1250,75 +1250,75 @@ with some custom extensions.
Available format strings:
================ ======================================== =====================
Format character Description Example output
================ ======================================== =====================
a ``'a.m.'`` or ``'p.m.'`` (Note that ``'a.m.'``
this is slightly different than PHP's
output, because this includes periods
to match Associated Press style.)
A ``'AM'`` or ``'PM'``. ``'AM'``
b Month, textual, 3 letters, lowercase. ``'jan'``
B Not implemented.
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
the "c" formatter will not add timezone
offset if value is a naive datetime
(see :class:`datetime.tzinfo`).
d Day of the month, 2 digits with ``'01'`` to ``'31'``
leading zeros.
D Day of the week, textual, 3 letters. ``'Fri'``
E Month, locale specific alternative
representation usually used for long
date representation. ``'listopada'`` (for Polish locale, as opposed to ``'Listopad'``)
f Time, in 12-hour hours and minutes, ``'1'``, ``'1:30'``
with minutes left off if they're zero.
Proprietary extension.
F Month, textual, long. ``'January'``
g Hour, 12-hour format without leading ``'1'`` to ``'12'``
zeros.
G Hour, 24-hour format without leading ``'0'`` to ``'23'``
zeros.
h Hour, 12-hour format. ``'01'`` to ``'12'``
H Hour, 24-hour format. ``'00'`` to ``'23'``
i Minutes. ``'00'`` to ``'59'``
I Not implemented.
j Day of the month without leading ``'1'`` to ``'31'``
zeros.
l Day of the week, textual, long. ``'Friday'``
L Boolean for whether it's a leap year. ``True`` or ``False``
m Month, 2 digits with leading zeros. ``'01'`` to ``'12'``
M Month, textual, 3 letters. ``'Jan'``
n Month without leading zeros. ``'1'`` to ``'12'``
N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'``
style. Proprietary extension.
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.'``
'a.m.'/'p.m.', with minutes left off
if they're zero and the special-case
strings 'midnight' and 'noon' if
appropriate. Proprietary extension.
r :rfc:`2822` formatted date. ``'Thu, 21 Dec 2000 16:01:07 +0200'``
s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'``
S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'``
month, 2 characters.
t Number of days in the given month. ``28`` to ``31``
T Time zone of this machine. ``'EST'``, ``'MDT'``
u Microseconds. ``0`` to ``999999``
U Seconds since the Unix Epoch
(January 1 1970 00:00:00 UTC).
w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday)
leading zeros.
W ISO-8601 week number of year, with ``1``, ``53``
weeks starting on Monday.
y Year, 2 digits. ``'99'``
Y Year, 4 digits. ``'1999'``
z Day of the year. ``0`` to ``365``
Z Time zone offset in seconds. The ``-43200`` to ``43200``
offset for timezones west of UTC is
always negative, and for those east of
UTC is always positive.
================ ======================================== =====================
================ ======================================== =====================
Format character Description Example output
================ ======================================== =====================
a ``'a.m.'`` or ``'p.m.'`` (Note that ``'a.m.'``
this is slightly different than PHP's
output, because this includes periods
to match Associated Press style.)
A ``'AM'`` or ``'PM'``. ``'AM'``
b Month, textual, 3 letters, lowercase. ``'jan'``
B Not implemented.
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
the "c" formatter will not add timezone
offset if value is a naive datetime
(see :class:`datetime.tzinfo`).
d Day of the month, 2 digits with ``'01'`` to ``'31'``
leading zeros.
D Day of the week, textual, 3 letters. ``'Fri'``
E Month, locale specific alternative
representation usually used for long
date representation. ``'listopada'`` (for Polish locale, as opposed to ``'Listopad'``)
f Time, in 12-hour hours and minutes, ``'1'``, ``'1:30'``
with minutes left off if they're zero.
Proprietary extension.
F Month, textual, long. ``'January'``
g Hour, 12-hour format without leading ``'1'`` to ``'12'``
zeros.
G Hour, 24-hour format without leading ``'0'`` to ``'23'``
zeros.
h Hour, 12-hour format. ``'01'`` to ``'12'``
H Hour, 24-hour format. ``'00'`` to ``'23'``
i Minutes. ``'00'`` to ``'59'``
I Not implemented.
j Day of the month without leading ``'1'`` to ``'31'``
zeros.
l Day of the week, textual, long. ``'Friday'``
L Boolean for whether it's a leap year. ``True`` or ``False``
m Month, 2 digits with leading zeros. ``'01'`` to ``'12'``
M Month, textual, 3 letters. ``'Jan'``
n Month without leading zeros. ``'1'`` to ``'12'``
N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'``
style. Proprietary extension.
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.'``
'a.m.'/'p.m.', with minutes left off
if they're zero and the special-case
strings 'midnight' and 'noon' if
appropriate. Proprietary extension.
r :rfc:`2822` formatted date. ``'Thu, 21 Dec 2000 16:01:07 +0200'``
s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'``
S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'``
month, 2 characters.
t Number of days in the given month. ``28`` to ``31``
T Time zone of this machine. ``'EST'``, ``'MDT'``
u Microseconds. ``0`` to ``999999``
U Seconds since the Unix Epoch
(January 1 1970 00:00:00 UTC).
w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday)
leading zeros.
W ISO-8601 week number of year, with ``1``, ``53``
weeks starting on Monday.
y Year, 2 digits. ``'99'``
Y Year, 4 digits. ``'1999'``
z Day of the year. ``0`` to ``365``
Z Time zone offset in seconds. The ``-43200`` to ``43200``
offset for timezones west of UTC is
always negative, and for those east of
UTC is always positive.
================ ======================================== =====================
.. versionadded:: 1.2
@ -1448,11 +1448,11 @@ escape
Escapes a string's HTML. Specifically, it makes these replacements:
* ``<`` is converted to ``&lt;``
* ``>`` is converted to ``&gt;``
* ``'`` (single quote) is converted to ``&#39;``
* ``"`` (double quote) is converted to ``&quot;``
* ``&`` is converted to ``&amp;``
* ``<`` is converted to ``&lt;``
* ``>`` is converted to ``&gt;``
* ``'`` (single quote) is converted to ``&#39;``
* ``"`` (double quote) is converted to ``&quot;``
* ``&`` is converted to ``&amp;``
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
@ -2320,9 +2320,9 @@ django.contrib.markup
A collection of template filters that implement these common markup languages:
* Textile
* Markdown
* reST (reStructuredText)
* Textile
* Markdown
* reST (reStructuredText)
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
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)
for details on how to set or alter the database character set encoding.
* MySQL users, refer to the `MySQL manual`_ (section 9.1.3.2 for MySQL 5.1)
for details on how to set or alter the database character set encoding.
* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 21.2.2 in
PostgreSQL 8) for details on creating databases with the correct encoding.
* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 21.2.2 in
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
for internal encoding.
* SQLite users, there is nothing you need to do. SQLite always uses UTF-8
for internal encoding.
.. _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
@ -106,35 +106,35 @@ Conversion functions
The ``django.utils.encoding`` module contains a few functions that are handy
for converting back and forth between Unicode and bytestrings.
* ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
converts its input to a Unicode string. The ``encoding`` parameter
specifies the input encoding. (For example, Django uses this internally
when processing form input data, which might not be UTF-8 encoded.) The
``strings_only`` parameter, if set to True, will result in Python
numbers, booleans and ``None`` not being converted to a string (they keep
their original types). The ``errors`` parameter takes any of the values
that are accepted by Python's ``unicode()`` function for its error
handling.
* ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
converts its input to a Unicode string. The ``encoding`` parameter
specifies the input encoding. (For example, Django uses this internally
when processing form input data, which might not be UTF-8 encoded.) The
``strings_only`` parameter, if set to True, will result in Python
numbers, booleans and ``None`` not being converted to a string (they keep
their original types). The ``errors`` parameter takes any of the values
that are accepted by Python's ``unicode()`` function for its error
handling.
If you pass ``smart_unicode()`` an object that has a ``__unicode__``
method, it will use that method to do the conversion.
If you pass ``smart_unicode()`` an object that has a ``__unicode__``
method, it will use that method to do the conversion.
* ``force_unicode(s, encoding='utf-8', strings_only=False,
errors='strict')`` is identical to ``smart_unicode()`` in almost all
cases. The difference is when the first argument is a :ref:`lazy
translation <lazy-translations>` instance. While ``smart_unicode()``
preserves lazy translations, ``force_unicode()`` forces those objects to a
Unicode string (causing the translation to occur). Normally, you'll want
to use ``smart_unicode()``. However, ``force_unicode()`` is useful in
template tags and filters that absolutely *must* have a string to work
with, not just something that can be converted to a string.
* ``force_unicode(s, encoding='utf-8', strings_only=False,
errors='strict')`` is identical to ``smart_unicode()`` in almost all
cases. The difference is when the first argument is a :ref:`lazy
translation <lazy-translations>` instance. While ``smart_unicode()``
preserves lazy translations, ``force_unicode()`` forces those objects to a
Unicode string (causing the translation to occur). Normally, you'll want
to use ``smart_unicode()``. However, ``force_unicode()`` is useful in
template tags and filters that absolutely *must* have a string to work
with, not just something that can be converted to a string.
* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
is essentially the opposite of ``smart_unicode()``. It forces the first
argument to a bytestring. The ``strings_only`` parameter has the same
behavior as for ``smart_unicode()`` and ``force_unicode()``. This is
slightly different semantics from Python's builtin ``str()`` function,
but the difference is needed in a few places within Django's internals.
* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
is essentially the opposite of ``smart_unicode()``. It forces the first
argument to a bytestring. The ``strings_only`` parameter has the same
behavior as for ``smart_unicode()`` and ``force_unicode()``. This is
slightly different semantics from Python's builtin ``str()`` function,
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
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
Django provides some assistance.
* The function ``django.utils.encoding.iri_to_uri()`` implements the
conversion from IRI to URI as required by the specification (:rfc:`3987`).
* The function ``django.utils.encoding.iri_to_uri()`` implements the
conversion from IRI to URI as required by the specification (:rfc:`3987`).
* The functions ``django.utils.http.urlquote()`` and
``django.utils.http.urlquote_plus()`` are versions of Python's standard
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
characters. (The data is converted to UTF-8 prior to encoding.)
* The functions ``django.utils.http.urlquote()`` and
``django.utils.http.urlquote_plus()`` are versions of Python's standard
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
characters. (The data is converted to UTF-8 prior to encoding.)
These two groups of functions have slightly different purposes, and it's
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:
* Always return Unicode strings from a template tag's ``render()`` method
and from template filters.
* Always return Unicode strings from a template tag's ``render()`` method
and from template filters.
* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these
places. Tag rendering and filter calls occur as the template is being
rendered, so there is no advantage to postponing the conversion of lazy
translation objects into strings. It's easier to work solely with Unicode
strings at that point.
* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these
places. Tag rendering and filter calls occur as the template is being
rendered, so there is no advantage to postponing the conversion of lazy
translation objects into strings. It's easier to work solely with Unicode
strings at that point.
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
arguments to it. The transformation is as follows:
* All keyword parameter names are turned to lowercase, and underscores
are converted to hyphens.
* If the value of a parameter is ``True`` (exactly ``True``, not just a
true value), only the parameter name is added to the header.
* All other parameters are added with their value, after applying
``str()`` to it.
* All keyword parameter names are turned to lowercase, and underscores
are converted to hyphens.
* If the value of a parameter is ``True`` (exactly ``True``, not just a
true value), only the parameter name is added to the header.
* All other parameters are added with their value, after applying
``str()`` to it.
.. 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:
* ``ETag``
* ``Last-Modified``
* ``Expires``
* ``Cache-Control``
* ``ETag``
* ``Last-Modified``
* ``Expires``
* ``Cache-Control``
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:
* ``False`` = left-to-right layout
* ``True`` = right-to-left layout
* ``False`` = left-to-right layout
* ``True`` = right-to-left layout
.. 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:
* Django now uses a more consistent and natural filtering interface for
retrieving objects from the database.
* Django now uses a more consistent and natural filtering interface for
retrieving objects from the database.
* User-defined models, functions and constants now appear in the module
namespace they were defined in. (Previously everything was magically
transferred to the django.models.* namespace.)
* User-defined models, functions and constants now appear in the module
namespace they were defined in. (Previously everything was magically
transferred to the django.models.* namespace.)
* Some optional applications, such as the FlatPage, Sites and Redirects
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
database tables.
* Some optional applications, such as the FlatPage, Sites and Redirects
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
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
backends for authenticating users against alternate systems, such as
LDAP.
* We've added the ability to write custom authentication and authorization
backends for authenticating users against alternate systems, such as
LDAP.
* We've made it easier to add custom table-level functions to models,
through a new "Manager" API.
* We've made it easier to add custom table-level functions to models,
through a new "Manager" API.
* 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
up just to serve dynamic pages. In other words, you can just use
URLconfs/views on their own. Previously, the framework required that a
database be configured, regardless of whether you actually used it.
* 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
up just to serve dynamic pages. In other words, you can just use
URLconfs/views on their own. Previously, the framework required that a
database be configured, regardless of whether you actually used it.
* 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
post_save() method hooks.
* 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
post_save() method hooks.
* Individual pieces of the framework now can be configured without
requiring the setting of an environment variable. This permits use of,
for example, the Django templating system inside other applications.
* Individual pieces of the framework now can be configured without
requiring the setting of an environment variable. This permits use of,
for example, the Django templating system inside other applications.
* More and more parts of the framework have been internationalized, as
we've expanded internationalization (i18n) support. The Django
codebase, including code and templates, has now been translated, at least
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.
* More and more parts of the framework have been internationalized, as
we've expanded internationalization (i18n) support. The Django
codebase, including code and templates, has now been translated, at least
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.
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,

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

View File

@ -562,17 +562,17 @@ following, replacing ``<app>`` in the code below with each app's name:
Notes:
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
porting floats to decimals with SQLite possible.
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
porting floats to decimals with SQLite possible.
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
this data in the third step, of course.
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
this data in the third step, of course.
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
this procedure for any of the standard Django models.
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
this procedure for any of the standard Django models.
If something goes wrong in the above process, just copy your backed up
database file over the original file and start again.
@ -717,13 +717,13 @@ a sequence of tuples.
To update your code:
1. Use :class:`django.utils.datastructures.SortedDict` wherever you were
using ``django.newforms.forms.SortedDictFromList``.
1. Use :class:`django.utils.datastructures.SortedDict` wherever you were
using ``django.newforms.forms.SortedDictFromList``.
2. Because :meth:`django.utils.datastructures.SortedDict.copy` doesn't
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
``copy.deepcopy`` directly.
2. Because :meth:`django.utils.datastructures.SortedDict.copy` doesn't
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
``copy.deepcopy`` directly.
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
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
running into.
@ -142,7 +142,7 @@ running into.
Additionally, discussion of Django development, including progress toward the
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
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:
* :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
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
:doc:`testing framework </topics/testing>`:
* The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler.
* The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler.
* It's now easier to get at the template context in the response returned
the test client: you'll simply access the context as
``request.context[key]``. The old way, which treats ``request.context``
as a list of contexts, one for each rendered template, is still
available if you need it.
* It's now easier to get at the template context in the response returned
the test client: you'll simply access the context as
``request.context[key]``. The old way, which treats ``request.context``
as a list of contexts, one for each rendered template, is still
available if you need it.
Conditional view processing
---------------------------
@ -129,30 +129,30 @@ Other improvements
Finally, a grab-bag of other neat features made their way into this beta
release, including:
* The :djadmin:`dumpdata` management command now accepts individual
model names as arguments, allowing you to export the data just from
particular models.
* The :djadmin:`dumpdata` management command now accepts individual
model names as arguments, allowing you to export the data just from
particular models.
* There's a new :tfilter:`safeseq` template filter which works just like
:tfilter:`safe` for lists, marking each item in the list as safe.
* There's a new :tfilter:`safeseq` template filter which works just like
:tfilter:`safe` for lists, marking each item in the list as safe.
* :doc:`Cache backends </topics/cache>` now support ``incr()`` and
``decr()`` commands to increment and decrement the value of a cache key.
On cache backends that support atomic increment/decrement -- most
notably, the memcached backend -- these operations will be atomic, and
quite fast.
* :doc:`Cache backends </topics/cache>` now support ``incr()`` and
``decr()`` commands to increment and decrement the value of a cache key.
On cache backends that support atomic increment/decrement -- most
notably, the memcached backend -- these operations will be atomic, and
quite fast.
* Django now can :doc:`easily delegate authentication to the Web server
</howto/auth-remote-user>` via a new authentication backend that supports
the standard ``REMOTE_USER`` environment variable used for this purpose.
* Django now can :doc:`easily delegate authentication to the Web server
</howto/auth-remote-user>` via a new authentication backend that supports
the standard ``REMOTE_USER`` environment variable used for this purpose.
* 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.
* 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.
* The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL
autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific
feature, that can make certain read-heavy applications a good deal
faster.
* The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL
autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific
feature, that can make certain read-heavy applications a good deal
faster.
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
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
running into.
@ -187,7 +187,7 @@ running into.
Additionally, discussion of Django development, including progress toward the
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
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:
* :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
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
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
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
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
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:
* :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
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
requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
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.

View File

@ -93,13 +93,13 @@ other than raise a ``DeprecationWarning``.
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
it to support your particular proxy (if necessary).
* Verify that it works correctly with your upstream proxy, modifying
it to support your particular proxy (if necessary).
* Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a
piece of middleware in your own project.
* Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a
piece of middleware in your own project.
__ 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:
* You should no longer use ``AdminSite.root()`` to register that admin
views. That is, if your URLconf contains the line::
* You should no longer use ``AdminSite.root()`` to register that admin
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.
@ -289,15 +289,15 @@ Test client improvements
A couple of small -- but highly useful -- improvements have been made to the
test client:
* The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler.
* The test :class:`Client` now can automatically follow redirects with the
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
makes testing views that issue redirects simpler.
* It's now easier to get at the template context in the response returned
the test client: you'll simply access the 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
chain, is still available if you need it.
* It's now easier to get at the template context in the response returned
the test client: you'll simply access the 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
chain, is still available if you need it.
New admin features
------------------
@ -352,16 +352,16 @@ GeoDjango
In Django 1.1, GeoDjango_ (i.e. ``django.contrib.gis``) has several new
features:
* Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial
backend.
* Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial
backend.
* Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``)
and ``F`` expressions.
* Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``)
and ``F`` expressions.
* New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and
``snap_to_grid``.
* New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and
``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`_.
@ -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
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
join the discussions!
@ -454,7 +454,7 @@ join the discussions!
Django's online documentation also includes pointers on how to 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 or simply
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
changes that developers must be aware of:
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and
**will be removed completely in Django 1.4**, in favor of a template tag that
should be inserted into forms.
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated, and
**will be removed completely in Django 1.4**, in favor of a template tag that
should be inserted into forms.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the ``csrf_token`` template tag in the template, so if you
have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the ``csrf_token`` template tag in the template, so if you
have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates.
.. admonition:: Documentation removed
.. admonition:: Documentation removed
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.
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.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
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
on how to do this are found in the CSRF docs.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
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
on how to do this are found in the CSRF docs.
* CSRF-related code has moved from ``contrib`` to ``core`` (with
backwards compatible imports in the old locations, which are
deprecated).
* CSRF-related code has moved from ``contrib`` to ``core`` (with
backwards compatible imports in the old locations, which are
deprecated).
: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
changes:
* If your class does not have special requirements for introspection (i.e. you
have not implemented ``__getattr__()`` or other methods that allow for
attributes not discoverable by normal mechanisms), you can simply remove the
``get_all_members()`` method. The default implementation on ``LazyObject``
will do the right thing.
* If your class does not have special requirements for introspection (i.e. you
have not implemented ``__getattr__()`` or other methods that allow for
attributes not discoverable by normal mechanisms), you can simply remove the
``get_all_members()`` method. The default implementation on ``LazyObject``
will do the right thing.
* If you have more complex requirements for introspection, first rename the
``get_all_members()`` method to ``__dir__()``. This is the standard method,
from Python 2.6 onwards, for supporting introspection. If you are require
support for Python < 2.6, add the following code to the class::
* If you have more complex requirements for introspection, first rename the
``get_all_members()`` method to ``__dir__()``. This is the standard method,
from Python 2.6 onwards, for supporting introspection. If you are require
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
-------------------------------
@ -282,20 +282,20 @@ The sample settings given previously would now be stored using::
This affects the following settings:
========================================= ==========================
Old setting New Setting
========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ==========================
========================================= ==========================
Old setting New Setting
========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ==========================
These changes are also required if you have manually created a database
connection using ``DatabaseWrapper()`` from your database backend of choice.
@ -367,9 +367,9 @@ or, when directly formatting a date value::
The same applies to the globals found in ``django.forms.fields``:
* ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_FORMATS``
* ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_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
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
running into.
@ -567,7 +567,7 @@ running into.
Additionally, discussion of Django development, including progress toward the
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
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:
* :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
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
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 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
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
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
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
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
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
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
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
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:
* :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
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
requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
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.

View File

@ -18,22 +18,22 @@ Overview
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
message for both anonymous and authenticated users.
* A new `user "messages" framework`_ with support for cookie- and session-based
message for both anonymous and authenticated users.
* Hooks for `object-level permissions`_, `permissions for anonymous users`_,
and `more flexible username requirements`_.
* Hooks for `object-level permissions`_, `permissions for anonymous users`_,
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
comparison operators.
* New :ref:`"smart" if template tag <new-in-1.2-smart-if>` which supports
comparison operators.
.. _multiple database connections: `support for multiple databases`_
.. _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
backwards-incompatible. The big changes are:
* Support for Python 2.3 has been dropped. See the full notes
below.
* Support for Python 2.3 has been dropped. See the full notes
below.
* 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 is removed in Django 1.4.
* 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 is removed in Django 1.4.
However, upgrading to the new CSRF protection framework requires a few
important backwards-incompatible changes, detailed in `CSRF Protection`_,
below.
However, upgrading to the new CSRF protection framework requires a few
important backwards-incompatible changes, detailed in `CSRF Protection`_,
below.
* Authors of custom :class:`~django.db.models.Field` subclasses should be
aware that a number of methods have had a change in prototype, detailed
under `get_db_prep_*() methods on Field`_, below.
* Authors of custom :class:`~django.db.models.Field` subclasses should be
aware that a number of methods have had a change in prototype, detailed
under `get_db_prep_*() methods on Field`_, below.
* The internals of template tags have changed somewhat; authors of custom
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
tags`_
* The internals of template tags have changed somewhat; authors of custom
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
tags`_
* The :func:`~django.contrib.auth.decorators.user_passes_test`,
:func:`~django.contrib.auth.decorators.login_required`, and
:func:`~django.contrib.auth.decorators.permission_required`, decorators
from :mod:`django.contrib.auth` only apply to functions and no longer
work on methods. There's a simple one-line fix `detailed below`_.
* The :func:`~django.contrib.auth.decorators.user_passes_test`,
:func:`~django.contrib.auth.decorators.login_required`, and
:func:`~django.contrib.auth.decorators.permission_required`, decorators
from :mod:`django.contrib.auth` only apply to functions and no longer
work on methods. There's a simple one-line fix `detailed below`_.
.. _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
should be aware of:
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and
will be removed completely in Django 1.4, in favor of a template tag that
should be inserted into forms.
* ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and
will be removed completely in Django 1.4, in favor of a template tag that
should be inserted into forms.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the ``csrf_token`` template tag in the template. If you
have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates.
* 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
have used custom templates for contrib views, you MUST READ THE UPGRADE
INSTRUCTIONS to fix those templates.
.. admonition:: Documentation removed
.. admonition:: Documentation removed
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.
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.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
default. This turns on CSRF protection by default, so views that accept
POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs.
* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
default. This turns on CSRF protection by default, so views that accept
POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs.
* All of the CSRF has moved from contrib to core (with backwards
compatible imports in the old locations, which are deprecated and
will cease to be supported in Django 1.4).
* All of the CSRF has moved from contrib to core (with backwards
compatible imports in the old locations, which are deprecated and
will cease to be supported in Django 1.4).
``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:
========================================= ==========================
Old setting New Setting
========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ==========================
========================================= ==========================
Old setting New Setting
========================================= ==========================
:setting:`DATABASE_ENGINE` :setting:`ENGINE`
:setting:`DATABASE_HOST` :setting:`HOST`
:setting:`DATABASE_NAME` :setting:`NAME`
:setting:`DATABASE_OPTIONS` :setting:`OPTIONS`
:setting:`DATABASE_PASSWORD` :setting:`PASSWORD`
:setting:`DATABASE_PORT` :setting:`PORT`
:setting:`DATABASE_USER` :setting:`USER`
:setting:`TEST_DATABASE_CHARSET` :setting:`TEST_CHARSET`
:setting:`TEST_DATABASE_COLLATION` :setting:`TEST_COLLATION`
:setting:`TEST_DATABASE_NAME` :setting:`TEST_NAME`
========================================= ==========================
These changes are also required if you have manually created a database
connection using ``DatabaseWrapper()`` from your database backend of choice.
@ -967,9 +967,9 @@ Or, when directly formatting a date value::
The same applies to the globals found in ``django.forms.fields``:
* ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_FORMATS``
* ``DEFAULT_DATE_INPUT_FORMATS``
* ``DEFAULT_TIME_INPUT_FORMATS``
* ``DEFAULT_DATETIME_INPUT_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
requests. These include:
* Improved tools for accessing and manipulating the current Site via
:func:`django.contrib.sites.models.get_current_site`.
* Improved tools for accessing and manipulating the current Site via
:func:`django.contrib.sites.models.get_current_site`.
* A :class:`~django.test.client.RequestFactory` for mocking
requests in tests.
* A :class:`~django.test.client.RequestFactory` for mocking
requests in tests.
* A new test assertion --
:meth:`~django.test.client.Client.assertNumQueries` -- making it
easier to test the database activity associated with a view.
* A new test assertion --
:meth:`~django.test.client.Client.assertNumQueries` -- making it
easier to test the database activity associated with a view.
.. _backwards-incompatible-changes-1.3-alpha-1:
@ -265,9 +265,9 @@ Localflavor changes
Django 1.3 introduces the following backwards-incompatible changes to
local flavors:
* Indonesia (id) -- The province "Nanggroe Aceh Darussalam (NAD)"
has been removed from the province list in favor of the new
official designation "Aceh (ACE)".
* Indonesia (id) -- The province "Nanggroe Aceh Darussalam (NAD)"
has been removed from the province list in favor of the new
official designation "Aceh (ACE)".
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.
The following modules and the views they contain have been deprecated:
* :mod:`django.views.generic.create_update`
* :mod:`django.views.generic.date_based`
* :mod:`django.views.generic.list_detail`
* :mod:`django.views.generic.simple`
* :mod:`django.views.generic.create_update`
* :mod:`django.views.generic.date_based`
* :mod:`django.views.generic.list_detail`
* :mod:`django.views.generic.simple`
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
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
running into.
@ -381,7 +381,7 @@ running into.
Additionally, discussion of Django development, including progress toward the
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
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:
* :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
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
release; these will typically be announced in advance on the
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
:djadmin:`runserver` command to modify this behavior:
* ``--nostatic``: prevents the :djadmin:`runserver` command from serving
files completely.
* ``--nostatic``: prevents the :djadmin:`runserver` command from serving
files completely.
* ``--insecure``: enables serving of static files even if running with
:setting:`DEBUG` set to False. (This is **not** recommended!)
* ``--insecure``: enables serving of static files even if running with
:setting:`DEBUG` set to False. (This is **not** recommended!)
See the :doc:`staticfiles reference documentation </ref/contrib/staticfiles>`
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:
* Two new global settings were added that will be used by, **but are not
limited to**, the :doc:`staticfiles</ref/contrib/staticfiles>` app:
* Two new global settings were added that will be used by, **but are not
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``
template tag was moved to Django's core (``django.templatetags.static``) and
renamed to :ttag:`get_static_prefix`.
* The ``django.contrib.staticfiles.templatetags.staticfiles.get_staticfiles_prefix``
template tag was moved to Django's core (``django.templatetags.static``) and
renamed to :ttag:`get_static_prefix`.
* The ``django.contrib.staticfiles.context_processors.staticfiles``
context processor was moved to Django's core
(``django.core.context_processors.static``) and renamed to
:func:`~django.core.context_processors.static`.
* The ``django.contrib.staticfiles.context_processors.staticfiles``
context processor was moved to Django's core
(``django.core.context_processors.static``) and renamed to
:func:`~django.core.context_processors.static`.
* :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
:setting:`MEDIA_URL` setting otherwise.
* :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
:setting:`MEDIA_URL` setting otherwise.
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
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
running into.
@ -217,7 +217,7 @@ running into.
Additionally, discussion of Django development, including progress toward the
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
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:
* :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
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:
* The :ttag:`include` tag now accepts a ``with`` option, allowing
you to specify context variables to the included template
* The :ttag:`include` tag now accepts a ``with`` option, allowing
you to specify context variables to the included template
* The :ttag:`include` tag now accepts an ``only`` option, allowing
you to exclude the current context from the included context
* The :ttag:`include` tag now accepts an ``only`` option, allowing
you to exclude the current context from the included context
* The :ttag:`with` tag now allows you to define multiple context
variables in a single :ttag:`with` block.
* The :ttag:`with` tag now allows you to define multiple context
variables in a single :ttag:`with` block.
* The :ttag:`load` tag now accepts a ``from`` argument, allowing
you to load a single tag or filter from a library.
* The :ttag:`load` tag now accepts a ``from`` argument, allowing
you to load a single tag or filter from a library.
TemplateResponse
~~~~~~~~~~~~~~~~
@ -573,39 +573,39 @@ found on disk, namely:
For translatable literals found in Python code and templates (``'django'``
gettext domain):
* Priorities of translations included with applications listed in the
:setting:`INSTALLED_APPS` setting were changed. To provide a behavior
consistent with other parts of Django that also use such setting (templates,
etc.) now, when building the translation that will be made available, the
apps listed first have higher precedence than the ones listed later.
* Priorities of translations included with applications listed in the
:setting:`INSTALLED_APPS` setting were changed. To provide a behavior
consistent with other parts of Django that also use such setting (templates,
etc.) now, when building the translation that will be made available, the
apps listed first have higher precedence than the ones listed later.
* Now it is possible to override the translations shipped with applications by
using the :setting:`LOCALE_PATHS` setting whose translations have now higher
precedence than the translations of :setting:`INSTALLED_APPS` applications.
The relative priority among the values listed in this setting has also been
modified so the paths listed first have higher precedence than the
ones listed later.
* Now it is possible to override the translations shipped with applications by
using the :setting:`LOCALE_PATHS` setting whose translations have now higher
precedence than the translations of :setting:`INSTALLED_APPS` applications.
The relative priority among the values listed in this setting has also been
modified so the paths listed first have higher precedence than the
ones listed later.
* The ``locale`` subdirectory of the directory containing the settings, that
usually coincides with and is know as the *project directory* is being
deprecated in this release as a source of translations. (the precedence of
these translations is intermediate between applications and :setting:`LOCALE_PATHS`
translations). See the `corresponding deprecated features section`_
of this document.
* The ``locale`` subdirectory of the directory containing the settings, that
usually coincides with and is know as the *project directory* is being
deprecated in this release as a source of translations. (the precedence of
these translations is intermediate between applications and :setting:`LOCALE_PATHS`
translations). See the `corresponding deprecated features section`_
of this document.
For translatable literals found in Javascript code (``'djangojs'`` gettext
domain):
* Similarly to the ``'django'`` domain translations: Overriding of
translations shipped with applications by using the :setting:`LOCALE_PATHS`
setting is now possible for this domain too. These translations have higher
precedence than the translations of Python packages passed to the
:ref:`javascript_catalog view <javascript_catalog-view>`. Paths listed first
have higher precedence than the ones listed later.
* Similarly to the ``'django'`` domain translations: Overriding of
translations shipped with applications by using the :setting:`LOCALE_PATHS`
setting is now possible for this domain too. These translations have higher
precedence than the translations of Python packages passed to the
:ref:`javascript_catalog view <javascript_catalog-view>`. Paths listed first
have higher precedence than the ones listed later.
* Translations under the ``locale`` subdirectory of the *project directory*
have never been taken in account for JavaScript translations and remain in
the same situation considering the deprecation of such location.
* Translations under the ``locale`` subdirectory of the *project directory*
have never been taken in account for JavaScript translations and remain in
the same situation considering the deprecation of such location.
.. _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:
* Set :setting:`BACKEND <CACHES-BACKEND>` to
``django.core.cache.backends.memcached.MemcachedCache`` or
``django.core.cache.backends.memcached.PyLibMCCache`` (depending
on your chosen memcached binding)
* Set :setting:`BACKEND <CACHES-BACKEND>` to
``django.core.cache.backends.memcached.MemcachedCache`` or
``django.core.cache.backends.memcached.PyLibMCCache`` (depending
on your chosen memcached binding)
* Set :setting:`LOCATION <CACHES-LOCATION>` to ``ip:port`` values,
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
``path`` is the path to a Memcached Unix socket file.
* Set :setting:`LOCATION <CACHES-LOCATION>` to ``ip:port`` values,
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
``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
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
keys in the :setting:`CACHES` setting. Valid arguments are as follows:
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
seconds, to use for the cache. This argument defaults to 300
seconds (5 minutes).
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
seconds, to use for the cache. This argument defaults to 300
seconds (5 minutes).
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
passed to cache backend. The list options understood by each
backend vary with each backend.
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
passed to cache backend. The list options understood by each
backend vary with each backend.
Cache backends that implement their own culling strategy (i.e.,
the ``locmem``, ``filesystem`` and ``database`` backends) will
honor the following options:
Cache backends that implement their own culling strategy (i.e.,
the ``locmem``, ``filesystem`` and ``database`` backends) will
honor the following options:
* ``MAX_ENTRIES``: the maximum number of entries allowed in
the cache before old values are deleted. This argument
defaults to ``300``.
* ``MAX_ENTRIES``: the maximum number of entries allowed in
the cache before old values are deleted. This argument
defaults to ``300``.
* ``CULL_FREQUENCY``: The fraction of entries that are culled
when ``MAX_ENTRIES`` is reached. The actual ratio is
``1/CULL_FREQUENCY``, so set ``CULL_FREQUENCY``: to ``2`` to
cull half of the entries when ``MAX_ENTRIES`` is reached.
* ``CULL_FREQUENCY``: The fraction of entries that are culled
when ``MAX_ENTRIES`` is reached. The actual ratio is
``1/CULL_FREQUENCY``, so set ``CULL_FREQUENCY``: to ``2`` to
cull half of the entries when ``MAX_ENTRIES`` is reached.
A value of ``0`` for ``CULL_FREQUENCY`` means that the
entire cache will be dumped when ``MAX_ENTRIES`` is reached.
This makes culling *much* faster at the expense of more
cache misses.
A value of ``0`` for ``CULL_FREQUENCY`` means that the
entire cache will be dumped when ``MAX_ENTRIES`` is reached.
This makes culling *much* faster at the expense of more
cache misses.
Cache backends backed by a third-party library will pass their
options directly to the underlying cache library. As a result,
the list of valid options depends on the library in use.
Cache backends backed by a third-party library will pass their
options directly to the underlying cache library. As a result,
the list of valid options depends on the library in use.
* :setting:`KEY_PREFIX <CACHES-KEY_PREFIX>`: A string that will be
automatically included (prepended by default) to all cache keys
used by the Django server.
* :setting:`KEY_PREFIX <CACHES-KEY_PREFIX>`: A string that will be
automatically included (prepended by default) to all cache keys
used by the Django server.
See the :ref:`cache documentation <cache_key_prefixing>` for
more information.
See the :ref:`cache documentation <cache_key_prefixing>` for
more information.
* :setting:`VERSION <CACHES-VERSION>`: The default version number
for cache keys generated by the Django server.
* :setting:`VERSION <CACHES-VERSION>`: The default version number
for cache keys generated by the Django server.
See the :ref:`cache documentation <cache_versioning>` for more
information.
See the :ref:`cache documentation <cache_versioning>` for more
information.
* :setting:`KEY_FUNCTION <CACHES-KEY_FUNCTION>`
A string containing a dotted path to a function that defines how
to compose a prefix, version and key into a final cache key.
* :setting:`KEY_FUNCTION <CACHES-KEY_FUNCTION>`
A string containing a dotted path to a function that defines how
to compose a prefix, version and key into a final cache key.
See the :ref:`cache documentation <cache_key_transformation>`
for more information.
See the :ref:`cache documentation <cache_key_transformation>`
for more information.
In this example, a filesystem backend is being configured with a timeout
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
:class:`~django.http.HttpResponse`:
* Sets the ``Last-Modified`` header to the current date/time when a fresh
(uncached) version of the page is requested.
* Sets the ``Last-Modified`` header to the current date/time when a fresh
(uncached) version of the page is requested.
* Sets the ``Expires`` header to the current date/time plus the defined
:setting:`CACHE_MIDDLEWARE_SECONDS`.
* Sets the ``Expires`` header to the current date/time plus the defined
:setting:`CACHE_MIDDLEWARE_SECONDS`.
* Sets the ``Cache-Control`` header to give a max age for the page --
again, from the :setting:`CACHE_MIDDLEWARE_SECONDS` setting.
* Sets the ``Cache-Control`` header to give a max age for the page --
again, from the :setting:`CACHE_MIDDLEWARE_SECONDS` setting.
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:
* 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
access example.com directly. The maintainers of example.com have no
knowledge of this caching; the ISP sits between example.com and your Web
browser, handling all of the caching transparently.
* 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
access example.com directly. The maintainers of example.com have no
knowledge of this caching; the ISP sits between example.com and your Web
browser, handling all of the caching transparently.
* 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
performance. In this case, each request first would be handled by the
proxy, and it would be passed to your application only if needed.
* 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
performance. In this case, each request first would be handled by the
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
appropriate headers, your browser will use the local cached copy for
subsequent requests to that page, without even contacting the Web page
again to see whether it has changed.
* Your Web browser caches pages, too. If a Web page sends out the
appropriate headers, your browser will use the local cached copy for
subsequent requests to that page, without even contacting the Web page
again to see whether it has changed.
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
@ -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
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
delivering the cached content when there are no changes. (Some caches
might deliver cached content even if the server page changed, simply
because the cache copy isn't yet expired.)
* Specify whether a cache should always check for newer versions, only
delivering the cached content when there are no changes. (Some caches
might deliver cached content even if the server page changed, simply
because the cache copy isn't yet expired.)
In Django, use the ``cache_control`` view decorator to specify these cache
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()``.
Here's a full list:
* ``public=True``
* ``private=True``
* ``no_cache=True``
* ``no_transform=True``
* ``must_revalidate=True``
* ``proxy_revalidate=True``
* ``max_age=num_seconds``
* ``s_maxage=num_seconds``
* ``public=True``
* ``private=True``
* ``no_cache=True``
* ``no_transform=True``
* ``must_revalidate=True``
* ``proxy_revalidate=True``
* ``max_age=num_seconds``
* ``s_maxage=num_seconds``
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
site's performance:
* ``django.middleware.http.ConditionalGetMiddleware`` adds support for
modern browsers to conditionally GET responses based on the ``ETag``
and ``Last-Modified`` headers.
* ``django.middleware.http.ConditionalGetMiddleware`` adds support for
modern browsers to conditionally GET responses based on the ``ETag``
and ``Last-Modified`` headers.
* :class:`django.middleware.gzip.GZipMiddleware` compresses responses for all
modern browsers, saving bandwidth and transfer time.
* :class:`django.middleware.gzip.GZipMiddleware` compresses responses for all
modern browsers, saving bandwidth and transfer time.
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``
header. The following middleware modules do so:
* ``SessionMiddleware`` adds ``Cookie``
* ``GZipMiddleware`` adds ``Accept-Encoding``
* ``LocaleMiddleware`` adds ``Accept-Language``
* ``SessionMiddleware`` adds ``Cookie``
* ``GZipMiddleware`` adds ``Accept-Encoding``
* ``LocaleMiddleware`` adds ``Accept-Language``
``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

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