summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2007-11-30 06:23:24 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2007-11-30 06:23:24 +0000
commitc81b01e060ad80a5c4df579a96ff737df2d336b3 (patch)
treed34a873e7b5e19f0e91424d4ab28e2f968233d63 /docs
parentf88babafc58eafece72d3f2f7444336c69196808 (diff)
newforms-admin: Merged from trunk up to [6775].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6777 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/authentication.txt2
-rw-r--r--docs/cache.txt34
-rw-r--r--docs/custom_model_fields.txt10
-rw-r--r--docs/databases.txt70
-rw-r--r--docs/django-admin.txt8
-rw-r--r--docs/flatpages.txt7
-rw-r--r--docs/i18n.txt6
-rw-r--r--docs/install.txt25
-rw-r--r--docs/middleware.txt3
-rw-r--r--docs/model-api.txt4
-rw-r--r--docs/modpython.txt13
-rw-r--r--docs/newforms.txt46
-rw-r--r--docs/release_notes_0.96.txt2
-rw-r--r--docs/settings.txt12
-rw-r--r--docs/syndication_feeds.txt21
-rw-r--r--docs/templates.txt40
-rw-r--r--docs/templates_python.txt137
-rw-r--r--docs/tutorial01.txt2
-rw-r--r--docs/unicode.txt2
-rw-r--r--docs/url_dispatch.txt2
20 files changed, 301 insertions, 145 deletions
diff --git a/docs/authentication.txt b/docs/authentication.txt
index aee9c5224a..2c34c6663d 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -170,7 +170,7 @@ The ``User`` model has a custom manager that has the following helper functions:
If no password is provided, ``set_unusable_password()`` will be called.
- See _`Creating users` for example usage.
+ See `Creating users`_ for example usage.
* ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')``
Returns a random password with the given length and given string of
diff --git a/docs/cache.txt b/docs/cache.txt
index 4f177b8c07..af6cb35c42 100644
--- a/docs/cache.txt
+++ b/docs/cache.txt
@@ -263,6 +263,18 @@ See the `middleware documentation`_ for more on middleware.
.. _`middleware documentation`: ../middleware/
+**New in Django development version**
+
+If a view sets its own cache expiry time (i.e. it has a ``max-age`` section in
+its ``Cache-Control`` header) then the page will be cached until the expiry
+time, rather than ``CACHE_MIDDLEWARE_SECONDS``. Using the decorators in
+``django.views.decorators.cache`` you can easily set a view's expiry time
+(using the ``cache_control`` decorator) or disable caching for a view (using
+the ``never_cache`` decorator). See the `using other headers`__ section for
+more on these decorators.
+
+__ `Controlling cache: Using other headers`_
+
The per-view cache
==================
@@ -291,7 +303,7 @@ minutes.
Template fragment caching
=========================
-**New in development version**.
+**New in development version**
If you're after even more control, you can also cache template fragments using
the ``cache`` template tag. To give your template access to this tag, put
@@ -307,18 +319,18 @@ and the name to give the cache fragment. For example::
{% endcache %}
Sometimes you might want to cache multiple copies of a fragment depending on
-some dynamic data that appears inside the fragment. For example you may want a
+some dynamic data that appears inside the fragment. For example, you might want a
separate cached copy of the sidebar used in the previous example for every user
-of your site. This can be easily achieved by passing additional arguments to
-the ``{% cache %}`` template tag to uniquely identify the cache fragment::
+of your site. Do this by passing additional arguments to the ``{% cache %}``
+template tag to uniquely identify the cache fragment::
{% load cache %}
{% cache 500 sidebar request.user.username %}
.. sidebar for logged in user ..
{% endcache %}
-If you need more than one argument to identify the fragment that's fine, simply
-pass as many arguments to ``{% cache %}`` as you need!
+It's perfectly fine to specify more than one argument to identify the fragment.
+Simply pass as many arguments to ``{% cache %}`` as you need.
The low-level cache API
=======================
@@ -358,16 +370,16 @@ get() can take a ``default`` argument::
>>> cache.get('my_key', 'has expired')
'has expired'
-To add a key only if it doesn't already exist, there is an add() method. It
-takes the same parameters as set(), but will not attempt to update the cache
-if the key specified is already present::
+**New in Django development version:** To add a key only if it doesn't already
+exist, use the ``add()`` method. It takes the same parameters as ``set()``, but
+it will not attempt to update the cache if the key specified is already present::
>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key')
'Initial value'
-There's also a get_many() interface that only hits the cache once. get_many()
+There's also a ``get_many()`` interface that only hits the cache once. ``get_many()``
returns a dictionary with all the keys you asked for that actually exist in the
cache (and haven't expired)::
@@ -566,7 +578,7 @@ the value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom
precedence, and the header values will be merged correctly.)
If you want to use headers to disable caching altogether,
-``django.views.decorators.never_cache`` is a view decorator that adds
+``django.views.decorators.cache.never_cache`` is a view decorator that adds
headers to ensure the response won't be cached by browsers or other caches. Example::
from django.views.decorators.cache import never_cache
diff --git a/docs/custom_model_fields.txt b/docs/custom_model_fields.txt
index c12d1844cd..74eb10aa82 100644
--- a/docs/custom_model_fields.txt
+++ b/docs/custom_model_fields.txt
@@ -56,7 +56,7 @@ would like to be able to things like this in our models (we assume the
We assign to and retrieve from the ``hand`` attribute in our model just like
any other Python class. The trick is to tell Django how to handle saving and
-loading such an object
+loading such an object.
In order to use the ``Hand`` class in our models, we **do not** have to change
this class at all. This is ideal, because it means you can easily write
@@ -98,7 +98,7 @@ For our ``Hand`` example, we could convert the card data to a string of 104
characters by concatenating all the cards together in a pre-determined order.
Say, all the *north* cards first, then the *east*, *south* and *west* cards, in
that order. So ``Hand`` objects can be saved to text or character columns in
-the database
+the database.
What does a field class do?
---------------------------
@@ -233,9 +233,9 @@ sure your field subclass uses ``django.db.models.SubfieldBase`` as its
metaclass. This ensures that the ``to_python()`` method, documented below_,
will always be called when the attribute is initialised.
-Our ``HandleField`` class now looks like this::
+Our ``HandField`` class now looks like this::
- class HandleField(models.Field):
+ class HandField(models.Field):
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
@@ -549,7 +549,7 @@ we can reuse some existing conversion code::
Some general advice
--------------------
-Writing a custom field can be a tricky process sometime, particularly if you
+Writing a custom field can be a tricky process sometimes, particularly if you
are doing complex conversions between your Python types and your database and
serialization formats. A couple of tips to make things go more smoothly:
diff --git a/docs/databases.txt b/docs/databases.txt
index 4530a1b896..d4853f75f8 100644
--- a/docs/databases.txt
+++ b/docs/databases.txt
@@ -172,22 +172,32 @@ storage engine, you have a couple of options.
.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB
-Oracle Notes
+Oracle notes
============
-Django supports `Oracle Database Server`_ versions 9i and higher. Oracle
+Django supports `Oracle Database Server`_ versions 9i and higher. Oracle
version 10g or later is required to use Django's ``regex`` and ``iregex`` query
-operators. You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer.
+operators. You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer.
.. _`Oracle Database Server`: http://www.oracle.com/
.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/
-To run ``python manage.py syncdb``, you'll need to create an Oracle database
-user with CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE, and CREATE TRIGGER
-privileges. To run Django's test suite, the user also needs
-CREATE and DROP DATABASE and CREATE and DROP TABLESPACE privileges.
+In order for the ``python manage.py syncdb`` command to work, your Oracle
+database user must have privileges to run the following commands:
-Connecting to the Database
+ * CREATE TABLE
+ * CREATE SEQUENCE
+ * CREATE PROCEDURE
+ * CREATE TRIGGER
+
+To run Django's test suite, the user needs these *additional* privileges:
+
+ * CREATE DATABASE
+ * DROP DATABASE
+ * CREATE TABLESPACE
+ * DROP TABLESPACE
+
+Connecting to the database
--------------------------
Your Django settings.py file should look something like this for Oracle::
@@ -213,29 +223,29 @@ and ``DATABASE_PORT`` like so::
You should supply both ``DATABASE_HOST`` and ``DATABASE_PORT``, or leave both
as empty strings.
-Tablespace Options
+Tablespace options
------------------
A common paradigm for optimizing performance in Oracle-based systems is the
use of `tablespaces`_ to organize disk layout. The Oracle backend supports
this use case by adding ``db_tablespace`` options to the ``Meta`` and
-``Field`` classes. (When using a backend that lacks support for tablespaces,
-these options are ignored.)
+``Field`` classes. (When you use a backend that lacks support for tablespaces,
+Django ignores these options.)
.. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace
A tablespace can be specified for the table(s) generated by a model by
-supplying the ``db_tablespace`` option inside the model's ``Meta`` class.
-Additionally, the ``db_tablespace`` option can be passed to a ``Field``
+supplying the ``db_tablespace`` option inside the model's ``class Meta``.
+Additionally, you can pass the ``db_tablespace`` option to a ``Field``
constructor to specify an alternate tablespace for the ``Field``'s column
-index. If no index would be created for the column, the ``db_tablespace``
+index. If no index would be created for the column, the ``db_tablespace``
option is ignored.
::
class TablespaceExample(models.Model):
- name = models.CharField(maxlength=30, db_index=True, db_tablespace="indexes")
- data = models.CharField(maxlength=255, db_index=True)
+ name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes")
+ data = models.CharField(max_length=255, db_index=True)
edges = models.ManyToManyField(to="self", db_tablespace="indexes")
class Meta:
@@ -243,46 +253,46 @@ option is ignored.
In this example, the tables generated by the ``TablespaceExample`` model
(i.e., the model table and the many-to-many table) would be stored in the
-``tables`` tablespace. The index for the name field and the indexes on the
-many-to-many table would be stored in the ``indexes`` tablespace. The ``data``
+``tables`` tablespace. The index for the name field and the indexes on the
+many-to-many table would be stored in the ``indexes`` tablespace. The ``data``
field would also generate an index, but no tablespace for it is specified, so
it would be stored in the model tablespace ``tables`` by default.
-Django does not create the tablespaces for you. Please refer to `Oracle's
+Django does not create the tablespaces for you. Please refer to `Oracle's
documentation`_ for details on creating and managing tablespaces.
.. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403
-Naming Issues
+Naming issues
-------------
-Oracle imposes a name length limit of 30 characters. To accommodate this, the
+Oracle imposes a name length limit of 30 characters. To accommodate this, the
backend truncates database identifiers to fit, replacing the final four
characters of the truncated name with a repeatable MD5 hash value.
-NULL and Empty Strings
+NULL and empty strings
----------------------
Django generally prefers to use the empty string ('') rather than NULL, but
-Oracle treats both identically. To get around this, the Oracle backend
+Oracle treats both identically. To get around this, the Oracle backend
coerces the ``null=True`` option on fields that permit the empty string as a
-value. When fetching from the database, it is assumed that a NULL value in
+value. When fetching from the database, it is assumed that a NULL value in
one of these fields really means the empty string, and the data is silently
converted to reflect this assumption.
-TextField Limitations
----------------------
+``TextField`` limitations
+-------------------------
-The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes
+The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes
some limitations on the usage of such LOB columns in general:
* LOB columns may not be used as primary keys.
* LOB columns may not be used in indexes.
- * LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that
+ * LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that
attempting to use the ``QuerySet.distinct`` method on a model that
includes ``TextField`` columns will result in an error when run against
- Oracle. A workaround to this is to keep ``TextField`` columns out of any
- models that you foresee performing ``.distinct`` queries on, and to
+ Oracle. A workaround to this is to keep ``TextField`` columns out of any
+ models that you foresee performing ``distinct()`` queries on, and to
include the ``TextField`` in a related model instead.
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index e751a7b3d9..2977f9908f 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -184,9 +184,9 @@ is being executed as an unattended, automated script.
Use ``--verbosity`` to specify the amount of notification and debug information
that ``django-admin.py`` should print to the console.
- * ``0`` means no input.
- * ``1`` means normal input (default).
- * ``2`` means verbose input.
+ * ``0`` means no output.
+ * ``1`` means normal output (default).
+ * ``2`` means verbose output.
Example usage::
@@ -651,7 +651,7 @@ To run the test server on port 7000 with ``fixture1`` and ``fixture2``::
that it doesn't matter whether the options come before or after the fixture
arguments.)
-To run on 1.2.3.4:7000 with a `test` fixture::
+To run on 1.2.3.4:7000 with a ``test`` fixture::
django-admin.py testserver --addrport 1.2.3.4:7000 test
diff --git a/docs/flatpages.txt b/docs/flatpages.txt
index d082090689..7c27fe8793 100644
--- a/docs/flatpages.txt
+++ b/docs/flatpages.txt
@@ -113,3 +113,10 @@ Here's a sample ``flatpages/default.html`` template::
{{ flatpage.content }}
</body>
</html>
+
+Since you're already entering raw HTML into the admin page for a flatpage,
+both ``flatpage.title`` and ``flatpage.content`` are marked as **not**
+requiring `automatic HTML escaping`_ in the template.
+
+.. _automatic HTML escaping: ../templates/#automatic-html-escaping
+
diff --git a/docs/i18n.txt b/docs/i18n.txt
index 2c43e7884e..1ae3024157 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -461,8 +461,8 @@ otherwise, they'll be tacked together without whitespace!
you'll be using to edit the content. Due to the way the ``gettext`` tools
work internally and because we want to allow non-ASCII source strings in
Django's core and your applications, you **must** use UTF-8 as the encoding
- for your PO file (this means that everybody will be using the same
- encoding, which is important when Django processes the PO files).
+ for your PO file. This means that everybody will be using the same
+ encoding, which is important when Django processes the PO files.
To reexamine all source code and templates for new translation strings and
update all message files for **all** languages, run this::
@@ -658,7 +658,7 @@ message file. The choice is yours.
of the settings file to determine this, and a settings file doesn't exist
if you're manually configuring your settings.)
-.. _settings documentation: ../settings/#using-settings-without-the-django-settings-module-environment-variable
+.. _settings documentation: ../settings/#using-settings-without-setting-django-settings-module
All message file repositories are structured the same way. They are:
diff --git a/docs/install.txt b/docs/install.txt
index 519bf2674c..08444d3a1a 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -187,10 +187,10 @@ latest bug fixes and improvements, follow these instructions:
"Where are my ``site-packages`` stored?" section above.)
Alternatively, you can define your ``PYTHONPATH`` environment variable
- so that it includes the ``django`` subdirectory of ``django-trunk``.
- This is perhaps the most convenient solution on Windows systems, which
- don't support symbolic links. (Environment variables can be defined on
- Windows systems `from the Control Panel`_.)
+ so that it includes the ``django-trunk`` directory. This is perhaps the
+ most convenient solution on Windows systems, which don't support symbolic
+ links. (Environment variables can be defined on Windows systems `from the
+ Control Panel`_.)
.. admonition:: What about Apache and mod_python?
@@ -204,11 +204,18 @@ latest bug fixes and improvements, follow these instructions:
.. _How to use Django with mod_python: ../modpython/
-4. Copy the file ``django-trunk/django/bin/django-admin.py`` to somewhere on
- your system path, such as ``/usr/local/bin`` (Unix) or ``C:\Python24\Scripts``
- (Windows). This step simply lets you type ``django-admin.py`` from within
- any directory, rather than having to qualify the command with the full path
- to the file.
+4. On Unix-like systems, create a symbolic link to the file
+ ``django-trunk/django/bin/django-admin.py`` in a directory on your system
+ path, such as ``/usr/local/bin``. For example::
+
+ ln -s `pwd`/django-trunk/django/bin/django-admin.py /usr/local/bin
+
+ This simply lets you type ``django-admin.py`` from within any directory,
+ rather than having to qualify the command with the full path to the file.
+
+ On Windows systems, the same result can be achieved by copying the file
+ ``django-trunk/django/bin/django-admin.py`` to somewhere on your system
+ path, for example ``C:\Python24\Scripts``.
You *don't* have to run ``python setup.py install``, because you've already
carried out the equivalent actions in steps 3 and 4.
diff --git a/docs/middleware.txt b/docs/middleware.txt
index 30a4899a3e..41b1a96b89 100644
--- a/docs/middleware.txt
+++ b/docs/middleware.txt
@@ -104,8 +104,7 @@ Handles conditional GET operations. If the response has a ``ETag`` or
``Last-Modified`` header, and the request has ``If-None-Match`` or
``If-Modified-Since``, the response is replaced by an HttpNotModified.
-Also removes the content from any response to a HEAD request and sets the
-``Date`` and ``Content-Length`` response-headers.
+Also sets the ``Date`` and ``Content-Length`` response-headers.
django.middleware.http.SetRemoteAddrFromForwardedFor
----------------------------------------------------
diff --git a/docs/model-api.txt b/docs/model-api.txt
index ca84c84d09..f39b711e84 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -50,7 +50,7 @@ The above ``Person`` model would create a database table like this::
Some technical notes:
* The name of the table, ``myapp_person``, is automatically derived from
- some model metadata but can be overridden. See _`Table names` below.
+ some model metadata but can be overridden. See `Table names`_ below.
* An ``id`` field is added automatically, but this behavior can be
overriden. See `Automatic primary key fields`_ below.
* The ``CREATE TABLE`` SQL in this example is formatted using PostgreSQL
@@ -1664,7 +1664,7 @@ Adding extra Manager methods
Adding extra ``Manager`` methods is the preferred way to add "table-level"
functionality to your models. (For "row-level" functionality -- i.e., functions
-that act on a single instance of a model object -- use _`Model methods`, not
+that act on a single instance of a model object -- use `Model methods`_, not
custom ``Manager`` methods.)
A custom ``Manager`` method can return anything you want. It doesn't have to
diff --git a/docs/modpython.txt b/docs/modpython.txt
index c739997ce4..aa1acf5864 100644
--- a/docs/modpython.txt
+++ b/docs/modpython.txt
@@ -89,18 +89,17 @@ path.
.. note::
- If you're using Windows, it is still recommended that you use forward
- slashes in the pathnames, even though Windows normally uses backslashes
- for its native separator. Apache knows how to convert from the forward
- slash format to the native format, so this approach is portable and easier
- to read (it avoids tricky problems with having to double-escape
- backslashes).
+ If you're using Windows, we still recommended that you use forward
+ slashes in the pathnames, even though Windows normally uses the backslash
+ character as its native separator. Apache knows how to convert from the
+ forward slash format to the native format, so this approach is portable and
+ easier to read. (It avoids tricky problems with having to double-escape
+ backslashes.)
This is valid even on a Windows system::
PythonPath "['c:/path/to/project'] + sys.path"
-
You can also add directives such as ``PythonAutoReload Off`` for performance.
See the `mod_python documentation`_ for a full list of options.
diff --git a/docs/newforms.txt b/docs/newforms.txt
index fe7106c26f..b06b0e02a2 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -756,6 +756,30 @@ For example::
</ul>
</form>
+Highlighting required fields in templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You may wish to show a visitor which fields are required. Here is the above
+example modified to insert an asterix after the label of each required field::
+
+ <form method="post" action="">
+ <dl>
+ {% for field in form %}
+ <dt>{{ field.label_tag }}{{ field.label }}{% if field.field.required %}*{% endif %}</dt>
+ <dd>{{ field }}</dd>
+ {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
+ {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
+ {% endfor %}
+ </dl>
+ <input type="submit" />
+ </form>
+
+The ``{% if field.field.required %}*{% endif %}`` fragment is the relevant
+addition here. It adds the asterix only if the field is required. Note that we
+check ``field.field.required`` and not ``field.required``. In the template,
+``field`` is a ``newforms.forms.BoundField`` instance, which holds the actual
+``Field`` instance in its ``field`` attribute.
+
Binding uploaded files to a form
--------------------------------
@@ -863,12 +887,11 @@ classes::
<li>Instrument: <input type="text" name="instrument" /></li>
<li>Haircut type: <input type="text" name="haircut_type" /></li>
-
Prefixes for forms
------------------
You can put several Django forms inside one ``<form>`` tag. To give each
-``Form`` its own namespace you need to use the ``prefix`` keyword argument::
+``Form`` its own namespace, use the ``prefix`` keyword argument::
>>> mother = PersonForm(prefix="mother")
>>> father = PersonForm(prefix="father")
@@ -879,7 +902,6 @@ You can put several Django forms inside one ``<form>`` tag. To give each
<li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li>
<li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li>
-
Fields
======
@@ -1852,7 +1874,11 @@ In addition, each generated form field has attributes set as follows:
* If the model field has ``choices`` set, then the form field's ``widget``
will be set to ``Select``, with choices coming from the model field's
- ``choices``.
+ ``choices``. The choices will normally include the blank choice which is
+ selected by default. If the field is required, this forces the user to
+ make a selection. The blank choice will not be included if the model
+ field has ``blank=False`` and an explicit ``default`` value (the
+ ``default`` value will be initially selected instead).
Finally, note that you can override the form field used for a given model
field. See "Overriding the default field types" below.
@@ -2098,10 +2124,14 @@ instance instead of a model class::
# Instantiate the form.
>>> f = AuthorForm()
-When a form created by ``form_for_instance()`` is created, the initial
-data values for the form fields are drawn from the instance. However,
-this data is not bound to the form. You will need to bind data to the
-form before the form can be saved.
+When a form created by ``form_for_instance()`` is created, the initial data
+values for the form fields are drawn from the instance. However, this data is
+not bound to the form. You will need to bind data to the form before the form
+can be saved.
+
+Unlike ``form_for_model()``, a choice field in form created by
+``form_for_instance()`` will not include the blank choice if the respective
+model field has ``blank=False``. The initial choice is drawn from the instance.
When you call ``save()`` on a form created by ``form_for_instance()``,
the database instance will be updated. As in ``form_for_model()``, ``save()``
diff --git a/docs/release_notes_0.96.txt b/docs/release_notes_0.96.txt
index 4227de8155..59931541e1 100644
--- a/docs/release_notes_0.96.txt
+++ b/docs/release_notes_0.96.txt
@@ -44,7 +44,7 @@ to this::
DATABASE_ENGINE = "mysql_old"
However, we strongly encourage MySQL users to upgrade to a more recent
-version of `MySQLdb` as soon as possible, The "mysql_old" backend is
+version of ``MySQLdb`` as soon as possible, The "mysql_old" backend is
provided only to ease this transition, and is considered deprecated;
aside from any necessary security fixes, it will not be actively
maintained, and it will be removed in a future release of Django.
diff --git a/docs/settings.txt b/docs/settings.txt
index 6241749753..1700c248c0 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -583,7 +583,7 @@ LOCALE_PATHS
Default: ``()`` (Empty tuple)
-A list of directories where Django looks for translation files.
+A tuple of directories where Django looks for translation files.
See the `internationalization docs section`_ explaining the variable and the
default behavior.
@@ -791,10 +791,12 @@ SESSION_COOKIE_PATH
Default: ``'/'``
-The path set on the session cookie. Should match the URL path of your Django
-installation (or be parent of that path). This is useful if you have multiple
-Django instances running under the same hostname; they can use different
-cookie paths and each instance will only see its own session cookie.
+The path set on the session cookie. This should either match the URL path of your
+Django installation or be parent of that path.
+
+This is useful if you have multiple Django instances running under the same
+hostname. They can use different cookie paths, and each instance will only see
+its own session cookie.
SESSION_COOKIE_SECURE
---------------------
diff --git a/docs/syndication_feeds.txt b/docs/syndication_feeds.txt
index 30943591b8..351cead39c 100644
--- a/docs/syndication_feeds.txt
+++ b/docs/syndication_feeds.txt
@@ -201,6 +201,8 @@ the feed.
An example makes this clear. Here's the code for these beat-specific feeds::
+ from django.contrib.syndication import FeedDoesNotExist
+
class BeatFeed(Feed):
def get_object(self, bits):
# In case of "/rss/beats/0613/foo/bar/baz/", or other such clutter,
@@ -213,6 +215,8 @@ An example makes this clear. Here's the code for these beat-specific feeds::
return "Chicagocrime.org: Crimes for beat %s" % obj.beat
def link(self, obj):
+ if not obj:
+ raise FeedDoesNotExist
return obj.get_absolute_url()
def description(self, obj):
@@ -246,11 +250,18 @@ request to the URL ``/rss/beats/0613/``:
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 uses the class attribute.
+ Inside the ``link()`` method, we handle the possibility that ``obj``
+ might be ``None``, which can occur when the URL isn't fully specified. In
+ some cases, you might want to do something else in this case, which would
+ mean you'd need to check for ``obj`` existing in other methods as well
+ (the ``link()`` method is called very early in the feed generation
+ process, so is a good place to bail out early).
+
* Finally, note that ``items()`` in this example also takes the ``obj``
argument. The algorithm for ``items`` is the same as described in the
previous step -- first, it tries ``items(obj)``, then ``items()``, then
@@ -553,15 +564,15 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
def ttl(self, obj):
"""
Takes the object returned by get_object() and returns the feed's
- TTL (Time to live) as a normal Python string.
+ TTL (Time To Live) as a normal Python string.
"""
def ttl(self):
"""
- Returns the feed's ttl as a normal Python string.
+ Returns the feed's TTL as a normal Python string.
"""
- ttl = 600 # Hard-coded Time to live.
+ ttl = 600 # Hard-coded Time To Live.
# ITEMS -- One of the following three is required. The framework looks
# for them in this order.
diff --git a/docs/templates.txt b/docs/templates.txt
index b85f108bbe..1c80f7578a 100644
--- a/docs/templates.txt
+++ b/docs/templates.txt
@@ -2,9 +2,11 @@
The Django template language: For template authors
==================================================
-This document explains the language syntax of the Django template system. If
-you're looking for a more technical perspective on how it works and how to
-extend it, see `The Django template language: For Python programmers`_.
+.. admonition:: About this document
+
+ This document explains the language syntax of the Django template system. If
+ you're looking for a more technical perspective on how it works and how to
+ extend it, see `The Django template language: For Python programmers`_.
Django's template language is designed to strike a balance between power and
ease. It's designed to feel comfortable to those used to working with HTML. If
@@ -280,7 +282,9 @@ Here are some tips for working with inheritance:
* 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
if you want to add to the contents of a parent block instead of
- completely overriding it.
+ completely overriding it. Data inserted using ``{{ block.super }}`` will
+ not be automatically escaped (see the `next section`_), since it was
+ already escaped, if necessary, in the parent template.
* For extra readability, you can optionally give a *name* to your
``{% endblock %}`` tag. For example::
@@ -299,6 +303,8 @@ it also defines the content that fills the hole in the *parent*. If there were
two similarly-named ``{% block %}`` tags in a template, that template's parent
wouldn't know which one of the blocks' content to use.
+.. _next section: #automatic-html-escaping
+
Automatic HTML escaping
=======================
@@ -397,6 +403,32 @@ auto-escaping is on, these extra filters won't change the output -- any
variables that use the ``escape`` filter do not have further automatic
escaping applied to them.
+String literals and automatic escaping
+--------------------------------------
+
+Sometimes you will pass a string literal as an argument to a filter. For
+example::
+
+ {{ data|default:"This is a string literal." }}
+
+All string literals are inserted **without** any automatic escaping into the
+template, if they are used (it's as if they were all passed through the
+``safe`` filter). The reasoning behind this is that the template author is in
+control of what goes into the string literal, so they can make sure the text
+is correctly escaped when the template is written.
+
+This means you would write ::
+
+ {{ data|default:"3 &gt; 2" }}
+
+...rather than ::
+
+ {{ data|default:"3 > 2" }} <-- Bad! Don't do this.
+
+This doesn't affect what happens to data coming from the variable itself.
+The variable's contents are still automatically escaped, if necessary, since
+they're beyond the control of the template author.
+
Using the built-in reference
============================
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index e4658f6461..64b67a1333 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -755,61 +755,106 @@ inside the template code:
``EscapeString`` and ``EscapeUnicode``. You will not normally need to worry
about these; they exist for the implementation of the ``escape`` filter.
-Inside your filter, you will need to think about three areas in order to be
-auto-escaping compliant:
+When you are writing a filter, your code will typically fall into one of two
+situations:
- 1. If your filter returns a string that is ready for direct output (it should
- be considered a "safe" string), you should call
- ``django.utils.safestring.mark_safe()`` on the result prior to returning.
- This will turn the result into the appropriate ``SafeData`` type. This is
- often the case when you are returning raw HTML, for example.
+ 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``. This attribute tells Django that
+ is 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. 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.
- 2. If your filter is given a "safe" string, is it guaranteed to return a
- "safe" string? If so, set the ``is_safe`` attribute on the function to be
- ``True``. For example, a filter that replaced a word consisting only of
- digits with the number spelt out in words is going to be
- safe-string-preserving, since it cannot introduce any of the five dangerous
- characters: <, >, ", ' or &. We can write::
+ 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 into
+ the result (aside from any that were already present), you should mark
+ your filter with ``is_safe``::
@register.filter
- def convert_to_words(value):
- # ... implementation here ...
- return result
+ def add_xx(value):
+ return '%sxx' % value
+ add_xx.is_safe = True
- convert_to_words.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".
- Note that this filter does not return a universally safe result (it does
- not return ``mark_safe(result)``) because if it is handed a raw string such
- as '<a>', this will need further escaping in an auto-escape environment.
- The ``is_safe`` attribute only talks about the the result when a safe
- string is passed into the filter.
+ By default, ``is_safe`` defaults to ``False`` and you can omit it from
+ any filters where it isn't required.
- 3. Will your filter behave differently depending upon whether auto-escaping
- is currently in effect or not? This is normally a concern when you are
- returning mixed content (HTML elements mixed with user-supplied content).
- For example, the ``ordered_list`` filter that ships with Django needs to
- know whether to escape its content or not. It will always return a safe
- string. Since it returns raw HTML, we cannot apply escaping to the
- result -- it needs to be done in-situ.
+ Be careful when deciding if your filter really does leave safe strings
+ as safe. Sometimes if you are *removing* characters, you can
+ 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.
- For these cases, the filter function needs to be told what the current
- auto-escaping setting is. Set the ``needs_autoescape`` attribute on the
- filter to ``True`` and have your function take an extra argument called
- ``autoescape`` with a default value of ``None``. When the filter is called,
- the ``autoescape`` keyword argument will be ``True`` if auto-escaping is in
- effect. For example, the ``unordered_list`` filter is written as::
+ 2. Alternatively, your filter code can manually take care of any necessary
+ escaping. This is usually necessary when you are 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.
- def unordered_list(value, autoescape=None):
- # ... lots of code here ...
+ To mark the output as a safe string, use
+ ``django.utils.safestring.mark_safe()``.
- return 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 will often
+ depend upon whether or not 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.
- unordered_list.is_safe = True
- unordered_list.needs_autoescape = True
+ In order for you 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`` is auto-escaping is in
+ effect and ``False`` otherwise.
-By default, both the ``is_safe`` and ``needs_autoescape`` attributes are
-``False``. You do not need to specify them if ``False`` is an acceptable
-value.
+ An example might make this clearer. Let's write a filter that emphasizes
+ the first character of a string::
+
+ 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
+
+ The ``needs_autoescape`` attribute on the filter function and the
+ ``autoescape`` keyword argument mean that our function will know whether
+ or not 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.
+
+ There is no need to worry about the ``is_safe`` attribute in this case
+ (although including it wouldn't hurt anything). Whenever you are manually
+ handling the auto-escaping issues and returning a safe string, the
+ ``is_safe`` attribute won't change anything either way.
Writing custom template tags
----------------------------
@@ -932,7 +977,9 @@ without having to be parsed multiple times.
Auto-escaping considerations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The output from template tags is not automatically run through the
+**New in Django development version**
+
+The output from template tags is **not** automatically run through the
auto-escaping filters. However, there are still a couple of things you should
keep in mind when writing a template tag:
@@ -1136,7 +1183,7 @@ on the object being edited -- so they're a perfect case for using a small
template that is filled with details from the current object. (In the admin's
case, this is the ``submit_row`` tag.)
-These sorts of tags are called `inclusion tags`.
+These sorts of tags are called "inclusion tags".
Writing inclusion tags is probably best demonstrated by example. Let's write a
tag that outputs a list of choices for a given ``Poll`` object, such as was
diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt
index 9e0c287346..b84ecd5f7e 100644
--- a/docs/tutorial01.txt
+++ b/docs/tutorial01.txt
@@ -47,7 +47,7 @@ will create a ``mysite`` directory in your current directory.
denied" when you try to run ``django-admin.py startproject``. This
is because, on Unix-based systems like OS X, a file must be marked
as "executable" before it can be run as a program. To do this, open
- Terminal.app and navigate (using the `cd` command) to the directory
+ Terminal.app and navigate (using the ``cd`` command) to the directory
where ``django-admin.py`` is installed, then run the command
``chmod +x django-admin.py``.
diff --git a/docs/unicode.txt b/docs/unicode.txt
index a0e2648f57..a2c4e7fbe6 100644
--- a/docs/unicode.txt
+++ b/docs/unicode.txt
@@ -136,7 +136,7 @@ for converting back and forth between Unicode and bytestrings.
* ``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
- behaviour as for ``smart_unicode()`` and ``force_unicode()``. This is
+ behavior as for ``smart_unicode()`` and ``force_unicode()``. This is
slightly different semantics from Python's builtin ``str()`` function,
but the difference is needed in a few places within Django's internals.
diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt
index 76a4e1b5f0..6ed7043fd5 100644
--- a/docs/url_dispatch.txt
+++ b/docs/url_dispatch.txt
@@ -237,7 +237,7 @@ include
-------
A function that takes a full Python import path to another URLconf that should
-be "included" in this place. See _`Including other URLconfs` below.
+be "included" in this place. See `Including other URLconfs`_ below.
Notes on capturing text in URLs
===============================