Removed use of non-standard indentation rules in docs, and the custom transform that supported them.

Doc writers should be aware that we are now back to normal ReST rules
regarding blockquotes.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16955 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant 2011-10-10 17:32:33 +00:00
parent af244e47cc
commit c61987d75a
8 changed files with 777 additions and 797 deletions

View File

@ -62,7 +62,6 @@ def setup(app):
app.add_config_value('django_next_version', '0.0', True) app.add_config_value('django_next_version', '0.0', True)
app.add_directive('versionadded', VersionDirective) app.add_directive('versionadded', VersionDirective)
app.add_directive('versionchanged', VersionDirective) app.add_directive('versionchanged', VersionDirective)
app.add_transform(SuppressBlockquotes)
app.add_builder(DjangoStandaloneHTMLBuilder) app.add_builder(DjangoStandaloneHTMLBuilder)
@ -99,27 +98,6 @@ class VersionDirective(Directive):
return ret return ret
class SuppressBlockquotes(transforms.Transform):
"""
Remove the default blockquotes that encase indented list, tables, etc.
"""
default_priority = 300
suppress_blockquote_child_nodes = (
nodes.bullet_list,
nodes.enumerated_list,
nodes.definition_list,
nodes.literal_block,
nodes.doctest_block,
nodes.line_block,
nodes.table
)
def apply(self):
for node in self.document.traverse(nodes.block_quote):
if len(node.children) == 1 and isinstance(node.children[0], self.suppress_blockquote_child_nodes):
node.replace_self(node.children[0])
class DjangoHTMLTranslator(SmartyPantsHTMLTranslator): class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
""" """
Django-specific reST to HTML tweaks. Django-specific reST to HTML tweaks.

View File

@ -16,31 +16,31 @@ Overview
There are seven steps in activating the Django admin site: There are seven steps in activating the Django admin site:
1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS` 1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
setting. setting.
2. The admin has four dependencies - :mod:`django.contrib.auth`, 2. The admin has four dependencies - :mod:`django.contrib.auth`,
:mod:`django.contrib.contenttypes`, :mod:`django.contrib.contenttypes`,
:mod:`django.contrib.messages` and :mod:`django.contrib.messages` and
:mod:`django.contrib.sessions`. If these applications are not :mod:`django.contrib.sessions`. If these applications are not
in your :setting:`INSTALLED_APPS` list, add them. in your :setting:`INSTALLED_APPS` list, add them.
3. Add ``django.contrib.messages.context_processors.messages`` to 3. Add ``django.contrib.messages.context_processors.messages`` to
:setting:`TEMPLATE_CONTEXT_PROCESSORS` and :setting:`TEMPLATE_CONTEXT_PROCESSORS` and
:class:`~django.contrib.messages.middleware.MessageMiddleware` to :class:`~django.contrib.messages.middleware.MessageMiddleware` to
:setting:`MIDDLEWARE_CLASSES`. :setting:`MIDDLEWARE_CLASSES`.
4. Determine which of your application's models should be editable in the 4. Determine which of your application's models should be editable in the
admin interface. admin interface.
5. For each of those models, optionally create a ``ModelAdmin`` class that 5. For each of those models, optionally create a ``ModelAdmin`` class that
encapsulates the customized admin functionality and options for that encapsulates the customized admin functionality and options for that
particular model. particular model.
6. Instantiate an ``AdminSite`` and tell it about each of your models and 6. Instantiate an ``AdminSite`` and tell it about each of your models and
``ModelAdmin`` classes. ``ModelAdmin`` classes.
7. Hook the ``AdminSite`` instance into your URLconf. 7. Hook the ``AdminSite`` instance into your URLconf.
Other topics Other topics
------------ ------------
@ -1735,11 +1735,11 @@ Templates which may be overridden per app or model
Not every template in ``contrib/admin/templates/admin`` may be overridden per Not every template in ``contrib/admin/templates/admin`` may be overridden per
app or per model. The following can: app or per model. The following can:
* ``app_index.html`` * ``app_index.html``
* ``change_form.html`` * ``change_form.html``
* ``change_list.html`` * ``change_list.html``
* ``delete_confirmation.html`` * ``delete_confirmation.html``
* ``object_history.html`` * ``object_history.html``
For those templates that cannot be overridden in this way, you may still For those templates that cannot be overridden in this way, you may still
override them for your entire project. Just place the new version in your override them for your entire project. Just place the new version in your
@ -1920,28 +1920,28 @@ accessible using Django's :ref:`URL reversing system <naming-url-patterns>`.
The :class:`AdminSite` provides the following named URL patterns: The :class:`AdminSite` provides the following named URL patterns:
====================== ======================== ============= ====================== ======================== =============
Page URL name Parameters Page URL name Parameters
====================== ======================== ============= ====================== ======================== =============
Index ``index`` Index ``index``
Logout ``logout`` Logout ``logout``
Password change ``password_change`` Password change ``password_change``
Password change done ``password_change_done`` Password change done ``password_change_done``
i18n javascript ``jsi18n`` i18n javascript ``jsi18n``
Application index page ``app_list`` ``app_label`` Application index page ``app_list`` ``app_label``
====================== ======================== ============= ====================== ======================== =============
Each :class:`ModelAdmin` instance provides an additional set of named URLs: Each :class:`ModelAdmin` instance provides an additional set of named URLs:
====================== =============================================== ============= ====================== =============================================== =============
Page URL name Parameters Page URL name Parameters
====================== =============================================== ============= ====================== =============================================== =============
Changelist ``{{ app_label }}_{{ model_name }}_changelist`` Changelist ``{{ app_label }}_{{ model_name }}_changelist``
Add ``{{ app_label }}_{{ model_name }}_add`` Add ``{{ app_label }}_{{ model_name }}_add``
History ``{{ app_label }}_{{ model_name }}_history`` ``object_id`` History ``{{ app_label }}_{{ model_name }}_history`` ``object_id``
Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id`` Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id``
Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id`` Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id``
====================== =============================================== ============= ====================== =============================================== =============
These named URLs are registered with the application namespace ``admin``, and These named URLs are registered with the application namespace ``admin``, and
with an instance namespace corresponding to the name of the Site instance. with an instance namespace corresponding to the name of the Site instance.

View File

@ -125,12 +125,12 @@ moderate comments"``) can approve and delete comments. This can also be
done through the ``admin`` as you'll see later. You might also want to done through the ``admin`` as you'll see later. You might also want to
customize the following templates: customize the following templates:
* ``flag.html`` * ``flag.html``
* ``flagged.html`` * ``flagged.html``
* ``approve.html`` * ``approve.html``
* ``approved.html`` * ``approved.html``
* ``delete.html`` * ``delete.html``
* ``deleted.html`` * ``deleted.html``
found under the directory structure we saw for ``form.html``. found under the directory structure we saw for ``form.html``.
@ -185,9 +185,9 @@ in-built with :doc:`generic comment moderation
</ref/contrib/comments/moderation>`. The comment moderation has the following </ref/contrib/comments/moderation>`. The comment moderation has the following
features (all of which or only certain can be enabled): features (all of which or only certain can be enabled):
* Enable comments for a particular model instance. * Enable comments for a particular model instance.
* Close comments after a particular (user-defined) number of days. * Close comments after a particular (user-defined) number of days.
* Email new comments to the site-staff. * Email new comments to the site-staff.
To enable comment moderation, we subclass the :class:`CommentModerator` and To enable comment moderation, we subclass the :class:`CommentModerator` and
register it with the moderation features we want. Let us suppose we want to register it with the moderation features we want. Let us suppose we want to

View File

@ -36,49 +36,49 @@ Supported countries
Countries currently supported by :mod:`~django.contrib.localflavor` are: Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Argentina_ * Argentina_
* Australia_ * Australia_
* Austria_ * Austria_
* Belgium_ * Belgium_
* Brazil_ * Brazil_
* Canada_ * Canada_
* Chile_ * Chile_
* China_ * China_
* Colombia_ * Colombia_
* Croatia_ * Croatia_
* Czech_ * Czech_
* Ecuador_ * Ecuador_
* Finland_ * Finland_
* France_ * France_
* Germany_ * Germany_
* Iceland_ * Iceland_
* India_ * India_
* Indonesia_ * Indonesia_
* Ireland_ * Ireland_
* Israel_ * Israel_
* Italy_ * Italy_
* Japan_ * Japan_
* Kuwait_ * Kuwait_
* Macedonia_ * Macedonia_
* Mexico_ * Mexico_
* `The Netherlands`_ * `The Netherlands`_
* Norway_ * Norway_
* Peru_ * Peru_
* Poland_ * Poland_
* Portugal_ * Portugal_
* Paraguay_ * Paraguay_
* Romania_ * Romania_
* Russia_ * Russia_
* Slovakia_ * Slovakia_
* Slovenia_ * Slovenia_
* `South Africa`_ * `South Africa`_
* Spain_ * Spain_
* Sweden_ * Sweden_
* Switzerland_ * Switzerland_
* Turkey_ * Turkey_
* `United Kingdom`_ * `United Kingdom`_
* `United States of America`_ * `United States of America`_
* Uruguay_ * Uruguay_
The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage, The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage,
containing useful code that is not specific to one particular country or culture. containing useful code that is not specific to one particular country or culture.

View File

@ -24,28 +24,28 @@ actually occurs until you do something to evaluate the queryset.
You can evaluate a ``QuerySet`` in the following ways: You can evaluate a ``QuerySet`` in the following ways:
* **Iteration.** A ``QuerySet`` is iterable, and it executes its database * **Iteration.** A ``QuerySet`` is iterable, and it executes its database
query the first time you iterate over it. For example, this will print query the first time you iterate over it. For example, this will print
the headline of all entries in the database:: the headline of all entries in the database::
for e in Entry.objects.all(): for e in Entry.objects.all():
print e.headline print e.headline
* **Slicing.** As explained in :ref:`limiting-querysets`, a ``QuerySet`` can * **Slicing.** As explained in :ref:`limiting-querysets`, a ``QuerySet`` can
be sliced, using Python's array-slicing syntax. Usually slicing a be sliced, using Python's array-slicing syntax. Usually slicing a
``QuerySet`` returns another (unevaluated) ``QuerySet``, but Django will ``QuerySet`` returns another (unevaluated) ``QuerySet``, but Django will
execute the database query if you use the "step" parameter of slice execute the database query if you use the "step" parameter of slice
syntax. syntax.
* **Pickling/Caching.** See the following section for details of what * **Pickling/Caching.** See the following section for details of what
is involved when `pickling QuerySets`_. The important thing for the is involved when `pickling QuerySets`_. The important thing for the
purposes of this section is that the results are read from the database. purposes of this section is that the results are read from the database.
* **repr().** A ``QuerySet`` is evaluated when you call ``repr()`` on it. * **repr().** A ``QuerySet`` is evaluated when you call ``repr()`` on it.
This is for convenience in the Python interactive interpreter, so you can This is for convenience in the Python interactive interpreter, so you can
immediately see your results when using the API interactively. immediately see your results when using the API interactively.
* **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it. * **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it.
This, as you might expect, returns the length of the result list. This, as you might expect, returns the length of the result list.
Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is
@ -54,7 +54,7 @@ You can evaluate a ``QuerySet`` in the following ways:
and Django provides a ``count()`` method for precisely this reason. See and Django provides a ``count()`` method for precisely this reason. See
``count()`` below. ``count()`` below.
* **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on * **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on
it. For example:: it. For example::
entry_list = list(Entry.objects.all()) entry_list = list(Entry.objects.all())
@ -64,7 +64,7 @@ You can evaluate a ``QuerySet`` in the following ways:
iterating over a ``QuerySet`` will take advantage of your database to iterating over a ``QuerySet`` will take advantage of your database to
load data and instantiate objects only as you need them. load data and instantiate objects only as you need them.
* **bool().** Testing a ``QuerySet`` in a boolean context, such as using * **bool().** Testing a ``QuerySet`` in a boolean context, such as using
``bool()``, ``or``, ``and`` or an ``if`` statement, will cause the query ``bool()``, ``or``, ``and`` or an ``if`` statement, will cause the query
to be executed. If there is at least one result, the ``QuerySet`` is to be executed. If there is at least one result, the ``QuerySet`` is
``True``, otherwise ``False``. For example:: ``True``, otherwise ``False``. For example::
@ -411,7 +411,7 @@ Example::
A few subtleties that are worth mentioning: A few subtleties that are worth mentioning:
* If you have a field called ``foo`` that is a * If you have a field called ``foo`` that is a
:class:`~django.db.models.ForeignKey`, the default ``values()`` call :class:`~django.db.models.ForeignKey`, the default ``values()`` call
will return a dictionary key called ``foo_id``, since this is the name will return a dictionary key called ``foo_id``, since this is the name
of the hidden model attribute that stores the actual value (the ``foo`` of the hidden model attribute that stores the actual value (the ``foo``
@ -431,11 +431,11 @@ A few subtleties that are worth mentioning:
>>> Entry.objects.values('blog_id') >>> Entry.objects.values('blog_id')
[{'blog_id': 1}, ...] [{'blog_id': 1}, ...]
* When using ``values()`` together with :meth:`distinct()`, be aware that * When using ``values()`` together with :meth:`distinct()`, be aware that
ordering can affect the results. See the note in :meth:`distinct` for ordering can affect the results. See the note in :meth:`distinct` for
details. details.
* If you use a ``values()`` clause after an :meth:`extra()` call, * If you use a ``values()`` clause after an :meth:`extra()` call,
any fields defined by a ``select`` argument in the :meth:`extra()` must any fields defined by a ``select`` argument in the :meth:`extra()` must
be explicitly included in the ``values()`` call. Any :meth:`extra()` call be explicitly included in the ``values()`` call. Any :meth:`extra()` call
made after a ``values()`` call will have its extra selected fields made after a ``values()`` call will have its extra selected fields
@ -524,10 +524,10 @@ model.
``datetime.datetime`` object in the result list is "truncated" to the given ``datetime.datetime`` object in the result list is "truncated" to the given
``type``. ``type``.
* ``"year"`` returns a list of all distinct year values for the field. * ``"year"`` returns a list of all distinct year values for the field.
* ``"month"`` returns a list of all distinct year/month values for the * ``"month"`` returns a list of all distinct year/month values for the
field. field.
* ``"day"`` returns a list of all distinct year/month/day values for the * ``"day"`` returns a list of all distinct year/month/day values for the
field. field.
``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or ``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or
@ -832,7 +832,8 @@ principle, so you should avoid them if possible.
Specify one or more of ``params``, ``select``, ``where`` or ``tables``. None Specify one or more of ``params``, ``select``, ``where`` or ``tables``. None
of the arguments is required, but you should use at least one of them. of the arguments is required, but you should use at least one of them.
* ``select`` * ``select``
The ``select`` argument lets you put extra fields in the ``SELECT`` The ``select`` argument lets you put extra fields in the ``SELECT``
clause. It should be a dictionary mapping attribute names to SQL clause. It should be a dictionary mapping attribute names to SQL
clauses to use to calculate that attribute. clauses to use to calculate that attribute.
@ -897,7 +898,8 @@ of the arguments is required, but you should use at least one of them.
tracking of parameters looks for ``%s`` and an escaped ``%`` character tracking of parameters looks for ``%s`` and an escaped ``%`` character
like this isn't detected. That will lead to incorrect results. like this isn't detected. That will lead to incorrect results.
* ``where`` / ``tables`` * ``where`` / ``tables``
You can define explicit SQL ``WHERE`` clauses — perhaps to perform You can define explicit SQL ``WHERE`` clauses — perhaps to perform
non-explicit joins — by using ``where``. You can manually add tables to non-explicit joins — by using ``where``. You can manually add tables to
the SQL ``FROM`` clause by using ``tables``. the SQL ``FROM`` clause by using ``tables``.
@ -934,7 +936,7 @@ of the arguments is required, but you should use at least one of them.
alias will be the same each time you construct the queryset in the same alias will be the same each time you construct the queryset in the same
way, so you can rely upon the alias name to not change. way, so you can rely upon the alias name to not change.
* ``order_by`` * ``order_by``
If you need to order the resulting queryset using some of the new If you need to order the resulting queryset using some of the new
fields or tables you have included via ``extra()`` use the ``order_by`` fields or tables you have included via ``extra()`` use the ``order_by``
@ -956,7 +958,7 @@ of the arguments is required, but you should use at least one of them.
This shows, by the way, that you can make multiple calls to ``extra()`` This shows, by the way, that you can make multiple calls to ``extra()``
and it will behave as you expect (adding new constraints each time). and it will behave as you expect (adding new constraints each time).
* ``params`` * ``params``
The ``where`` parameter described above may use standard Python The ``where`` parameter described above may use standard Python
database string placeholders — ``'%s'`` to indicate parameters the database string placeholders — ``'%s'`` to indicate parameters the
@ -1304,11 +1306,11 @@ are)::
This has a number of caveats though: This has a number of caveats though:
* The model's ``save()`` method will not be called, and the ``pre_save`` and * The model's ``save()`` method will not be called, and the ``pre_save`` and
``post_save`` signals will not be sent. ``post_save`` signals will not be sent.
* It does not work with child models in a multi-table inheritance scenario. * It does not work with child models in a multi-table inheritance scenario.
* If the model's primary key is an :class:`~django.db.models.AutoField` it * If the model's primary key is an :class:`~django.db.models.AutoField` it
does not retrieve and set the primary key attribute, as ``save()`` does. does not retrieve and set the primary key attribute, as ``save()`` does.
count count
~~~~~ ~~~~~

View File

@ -240,7 +240,7 @@ Caveats with support of certain databases
Django attempts to support as many features as possible on all database Django attempts to support as many features as possible on all database
backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It's a good idea to checkout our :doc:`notes on supported database </ref/databases>`: backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It's a good idea to checkout our :doc:`notes on supported database </ref/databases>`:
- :ref:`mysql-notes` - :ref:`mysql-notes`
- :ref:`sqlite-notes` - :ref:`sqlite-notes`
- :ref:`oracle-notes` - :ref:`oracle-notes`

View File

@ -14,10 +14,10 @@ Overview
The auth system consists of: The auth system consists of:
* Users * Users
* Permissions: Binary (yes/no) flags designating whether a user may perform * Permissions: Binary (yes/no) flags designating whether a user may perform
a certain task. a certain task.
* Groups: A generic way of applying labels and permissions to more than one * Groups: A generic way of applying labels and permissions to more than one
user. user.
Installation Installation
@ -26,11 +26,11 @@ Installation
Authentication support is bundled as a Django application in Authentication support is bundled as a Django application in
``django.contrib.auth``. To install it, do the following: ``django.contrib.auth``. To install it, do the following:
1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in 1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
your :setting:`INSTALLED_APPS` setting. your :setting:`INSTALLED_APPS` setting.
(The :class:`~django.contrib.auth.models.Permission` model in (The :class:`~django.contrib.auth.models.Permission` model in
:mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.) :mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.)
2. Run the command ``manage.py syncdb``. 2. Run the command ``manage.py syncdb``.
Note that the default :file:`settings.py` file created by Note that the default :file:`settings.py` file created by
:djadmin:`django-admin.py startproject <startproject>` includes :djadmin:`django-admin.py startproject <startproject>` includes
@ -715,27 +715,27 @@ Sent when a user logs in successfully.
Arguments sent with this signal: Arguments sent with this signal:
``sender`` ``sender``
As above: the class of the user that just logged in. As above: the class of the user that just logged in.
``request`` ``request``
The current :class:`~django.http.HttpRequest` instance. The current :class:`~django.http.HttpRequest` instance.
``user`` ``user``
The user instance that just logged in. The user instance that just logged in.
.. data:: django.contrib.auth.signals.user_logged_out .. data:: django.contrib.auth.signals.user_logged_out
Sent when the logout method is called. Sent when the logout method is called.
``sender`` ``sender``
As above: the class of the user that just logged out or ``None`` As above: the class of the user that just logged out or ``None``
if the user was not authenticated. if the user was not authenticated.
``request`` ``request``
The current :class:`~django.http.HttpRequest` instance. The current :class:`~django.http.HttpRequest` instance.
``user`` ``user``
The user instance that just logged out or ``None`` if the The user instance that just logged out or ``None`` if the
user was not authenticated. user was not authenticated.
@ -1354,12 +1354,12 @@ code.
The Django admin site uses permissions as follows: The Django admin site uses permissions as follows:
* Access to view the "add" form and add an object is limited to users with * Access to view the "add" form and add an object is limited to users with
the "add" permission for that type of object. the "add" permission for that type of object.
* Access to view the change list, view the "change" form and change an * Access to view the change list, view the "change" form and change an
object is limited to users with the "change" permission for that type of object is limited to users with the "change" permission for that type of
object. object.
* Access to delete an object is limited to users with the "delete" * Access to delete an object is limited to users with the "delete"
permission for that type of object. permission for that type of object.
Permissions are set globally per type of object, not per specific object Permissions are set globally per type of object, not per specific object
@ -1389,9 +1389,9 @@ Assuming you have an application with an
:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``, :attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
to test for basic permissions you should use: to test for basic permissions you should use:
* add: ``user.has_perm('foo.add_bar')`` * add: ``user.has_perm('foo.add_bar')``
* change: ``user.has_perm('foo.change_bar')`` * change: ``user.has_perm('foo.change_bar')``
* delete: ``user.has_perm('foo.delete_bar')`` * delete: ``user.has_perm('foo.delete_bar')``
.. _custom-permissions: .. _custom-permissions:

View File

@ -129,7 +129,7 @@ them in the :ref:`built-in filter reference <ref-templates-builtins-filters>`.
To give you a taste of what's available, here are some of the more commonly To give you a taste of what's available, here are some of the more commonly
used template filters: used template filters:
:tfilter:`default` :tfilter:`default`
If a variable is false or empty, use given default. Otherwise, use the If a variable is false or empty, use given default. Otherwise, use the
value of the variable value of the variable
@ -140,7 +140,7 @@ used template filters:
If ``value`` isn't provided or is empty, the above will display If ``value`` isn't provided or is empty, the above will display
"``nothing``". "``nothing``".
:tfilter:`length` :tfilter:`length`
Returns the length of the value. This works for both strings and lists; Returns the length of the value. This works for both strings and lists;
for example:: for example::
@ -148,7 +148,7 @@ used template filters:
If ``value`` is ``['a', 'b', 'c', 'd']``, the output will be ``4``. If ``value`` is ``['a', 'b', 'c', 'd']``, the output will be ``4``.
:tfilter:`striptags` :tfilter:`striptags`
Strips all [X]HTML tags. For example:: Strips all [X]HTML tags. For example::
{{ value|striptags }} {{ value|striptags }}
@ -183,7 +183,7 @@ them in the :ref:`built-in tag reference <ref-templates-builtins-tags>`. To give
you a taste of what's available, here are some of the more commonly used you a taste of what's available, here are some of the more commonly used
tags: tags:
:ttag:`for` :ttag:`for`
Loop over each item in an array. For example, to display a list of athletes Loop over each item in an array. For example, to display a list of athletes
provided in ``athlete_list``:: provided in ``athlete_list``::
@ -193,7 +193,7 @@ tags:
{% endfor %} {% endfor %}
</ul> </ul>
:ttag:`if` and ``else`` :ttag:`if` and ``else``
Evaluates a variable, and if that variable is "true" the contents of the Evaluates a variable, and if that variable is "true" the contents of the
block are displayed:: block are displayed::
@ -214,7 +214,7 @@ tags:
Athlete: {{ athlete_list.0.name }} Athlete: {{ athlete_list.0.name }}
{% endif %} {% endif %}
:ttag:`block` and :ttag:`extends` :ttag:`block` and :ttag:`extends`
Set up `template inheritance`_ (see below), a powerful way Set up `template inheritance`_ (see below), a powerful way
of cutting down on "boilerplate" in templates. of cutting down on "boilerplate" in templates.
@ -344,13 +344,13 @@ tag in a parent template is always used as a fallback.
You can use as many levels of inheritance as needed. One common way of using You can use as many levels of inheritance as needed. One common way of using
inheritance is the following three-level approach: inheritance is the following three-level approach:
* Create a ``base.html`` template that holds the main look-and-feel of your * Create a ``base.html`` template that holds the main look-and-feel of your
site. site.
* Create a ``base_SECTIONNAME.html`` template for each "section" of your * Create a ``base_SECTIONNAME.html`` template for each "section" of your
site. For example, ``base_news.html``, ``base_sports.html``. These site. For example, ``base_news.html``, ``base_sports.html``. These
templates all extend ``base.html`` and include section-specific templates all extend ``base.html`` and include section-specific
styles/design. styles/design.
* Create individual templates for each type of page, such as a news * Create individual templates for each type of page, such as a news
article or blog entry. These templates extend the appropriate section article or blog entry. These templates extend the appropriate section
template. template.
@ -359,26 +359,26 @@ content areas, such as section-wide navigation.
Here are some tips for working with inheritance: Here are some tips for working with inheritance:
* If you use :ttag:`{% extends %}<extends>` in a template, it must be the first template * If you use :ttag:`{% extends %}<extends>` in a template, it must be the first template
tag in that template. Template inheritance won't work, otherwise. tag in that template. Template inheritance won't work, otherwise.
* More :ttag:`{% block %}<block>` tags in your base templates are better. Remember, * More :ttag:`{% block %}<block>` tags in your base templates are better. Remember,
child templates don't have to define all parent blocks, so you can fill child templates don't have to define all parent blocks, so you can fill
in reasonable defaults in a number of blocks, then only define the ones in reasonable defaults in a number of blocks, then only define the ones
you need later. It's better to have more hooks than fewer hooks. you need later. It's better to have more hooks than fewer hooks.
* If you find yourself duplicating content in a number of templates, it * If you find yourself duplicating content in a number of templates, it
probably means you should move that content to a ``{% block %}`` in a probably means you should move that content to a ``{% block %}`` in a
parent template. parent template.
* If you need to get the content of the block from the parent template, * If you need to get the content of the block from the parent template,
the ``{{ block.super }}`` variable will do the trick. This is useful the ``{{ block.super }}`` variable will do the trick. This is useful
if you want to add to the contents of a parent block instead of if you want to add to the contents of a parent block instead of
completely overriding it. Data inserted using ``{{ block.super }}`` will completely overriding it. Data inserted using ``{{ block.super }}`` will
not be automatically escaped (see the `next section`_), since it was not be automatically escaped (see the `next section`_), since it was
already escaped, if necessary, in the parent template. already escaped, if necessary, in the parent template.
* For extra readability, you can optionally give a *name* to your * For extra readability, you can optionally give a *name* to your
``{% endblock %}`` tag. For example:: ``{% endblock %}`` tag. For example::
{% block content %} {% block content %}
@ -437,25 +437,25 @@ do potentially bad things. This type of security exploit is called a
To avoid this problem, you have two options: To avoid this problem, you have two options:
* One, you can make sure to run each untrusted variable through the * One, you can make sure to run each untrusted variable through the
:tfilter:`escape` filter (documented below), which converts potentially :tfilter:`escape` filter (documented below), which converts potentially
harmful HTML characters to unharmful ones. This was the default solution harmful HTML characters to unharmful ones. This was the default solution
in Django for its first few years, but the problem is that it puts the in Django for its first few years, but the problem is that it puts the
onus on *you*, the developer / template author, to ensure you're escaping onus on *you*, the developer / template author, to ensure you're escaping
everything. It's easy to forget to escape data. everything. It's easy to forget to escape data.
* Two, you can take advantage of Django's automatic HTML escaping. The * Two, you can take advantage of Django's automatic HTML escaping. The
remainder of this section describes how auto-escaping works. remainder of this section describes how auto-escaping works.
By default in Django, every template automatically escapes the output By default in Django, every template automatically escapes the output
of every variable tag. Specifically, these five characters are of every variable tag. Specifically, these five characters are
escaped: escaped:
* ``<`` is converted to ``&lt;`` * ``<`` is converted to ``&lt;``
* ``>`` is converted to ``&gt;`` * ``>`` is converted to ``&gt;``
* ``'`` (single quote) is converted to ``&#39;`` * ``'`` (single quote) is converted to ``&#39;``
* ``"`` (double quote) is converted to ``&quot;`` * ``"`` (double quote) is converted to ``&quot;``
* ``&`` is converted to ``&amp;`` * ``&`` is converted to ``&amp;``
Again, we stress that this behavior is on by default. If you're using Django's Again, we stress that this behavior is on by default. If you're using Django's
template system, you're protected. template system, you're protected.