diff options
| author | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-11-30 06:23:24 +0000 |
|---|---|---|
| committer | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-11-30 06:23:24 +0000 |
| commit | c81b01e060ad80a5c4df579a96ff737df2d336b3 (patch) | |
| tree | d34a873e7b5e19f0e91424d4ab28e2f968233d63 /docs | |
| parent | f88babafc58eafece72d3f2f7444336c69196808 (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.txt | 2 | ||||
| -rw-r--r-- | docs/cache.txt | 34 | ||||
| -rw-r--r-- | docs/custom_model_fields.txt | 10 | ||||
| -rw-r--r-- | docs/databases.txt | 70 | ||||
| -rw-r--r-- | docs/django-admin.txt | 8 | ||||
| -rw-r--r-- | docs/flatpages.txt | 7 | ||||
| -rw-r--r-- | docs/i18n.txt | 6 | ||||
| -rw-r--r-- | docs/install.txt | 25 | ||||
| -rw-r--r-- | docs/middleware.txt | 3 | ||||
| -rw-r--r-- | docs/model-api.txt | 4 | ||||
| -rw-r--r-- | docs/modpython.txt | 13 | ||||
| -rw-r--r-- | docs/newforms.txt | 46 | ||||
| -rw-r--r-- | docs/release_notes_0.96.txt | 2 | ||||
| -rw-r--r-- | docs/settings.txt | 12 | ||||
| -rw-r--r-- | docs/syndication_feeds.txt | 21 | ||||
| -rw-r--r-- | docs/templates.txt | 40 | ||||
| -rw-r--r-- | docs/templates_python.txt | 137 | ||||
| -rw-r--r-- | docs/tutorial01.txt | 2 | ||||
| -rw-r--r-- | docs/unicode.txt | 2 | ||||
| -rw-r--r-- | docs/url_dispatch.txt | 2 |
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 > 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 ``&`` + into ``&``, 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 =============================== |
