mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed many more ReST indentation errors, somehow accidentally missed from [16955]
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16983 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -14,12 +14,12 @@ dealing with Apache, you can configuring Apache to authenticate against Django's
|
||||
:doc:`authentication system </topics/auth>` directly. For example, you
|
||||
could:
|
||||
|
||||
* Serve static/media files directly from Apache only to authenticated users.
|
||||
* Serve static/media files directly from Apache only to authenticated users.
|
||||
|
||||
* Authenticate access to a Subversion_ repository against Django users with
|
||||
a certain permission.
|
||||
* Authenticate access to a Subversion_ repository against Django users with
|
||||
a certain permission.
|
||||
|
||||
* Allow certain users to connect to a WebDAV share created with mod_dav_.
|
||||
* Allow certain users to connect to a WebDAV share created with mod_dav_.
|
||||
|
||||
.. _Subversion: http://subversion.tigris.org/
|
||||
.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
|
||||
@@ -93,29 +93,29 @@ By default, the authentication handler will limit access to the ``/example/``
|
||||
location to users marked as staff members. You can use a set of
|
||||
``PythonOption`` directives to modify this behavior:
|
||||
|
||||
================================ =========================================
|
||||
``PythonOption`` Explanation
|
||||
================================ =========================================
|
||||
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
|
||||
those with the ``is_staff`` flag set)
|
||||
will be allowed.
|
||||
================================ =========================================
|
||||
``PythonOption`` Explanation
|
||||
================================ =========================================
|
||||
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
|
||||
those with the ``is_staff`` flag set)
|
||||
will be allowed.
|
||||
|
||||
Defaults to ``on``.
|
||||
Defaults to ``on``.
|
||||
|
||||
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
|
||||
those with the ``is_superuser`` flag set)
|
||||
will be allowed.
|
||||
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
|
||||
those with the ``is_superuser`` flag set)
|
||||
will be allowed.
|
||||
|
||||
Defaults to ``off``.
|
||||
Defaults to ``off``.
|
||||
|
||||
``DjangoPermissionName`` The name of a permission to require for
|
||||
access. See :ref:`custom permissions
|
||||
<custom-permissions>` for more
|
||||
information.
|
||||
``DjangoPermissionName`` The name of a permission to require for
|
||||
access. See :ref:`custom permissions
|
||||
<custom-permissions>` for more
|
||||
information.
|
||||
|
||||
By default no specific permission will be
|
||||
required.
|
||||
================================ =========================================
|
||||
By default no specific permission will be
|
||||
required.
|
||||
================================ =========================================
|
||||
|
||||
Note that sometimes ``SetEnv`` doesn't play well in this mod_python
|
||||
configuration, for reasons unknown. If you're having problems getting
|
||||
|
||||
@@ -37,11 +37,11 @@ You'll need to follow these steps:
|
||||
Your custom storage system may override any of the storage methods explained in
|
||||
:doc:`/ref/files/storage`, but you **must** implement the following methods:
|
||||
|
||||
* :meth:`Storage.delete`
|
||||
* :meth:`Storage.exists`
|
||||
* :meth:`Storage.listdir`
|
||||
* :meth:`Storage.size`
|
||||
* :meth:`Storage.url`
|
||||
* :meth:`Storage.delete`
|
||||
* :meth:`Storage.exists`
|
||||
* :meth:`Storage.listdir`
|
||||
* :meth:`Storage.size`
|
||||
* :meth:`Storage.url`
|
||||
|
||||
You'll also usually want to use hooks specifically designed for custom storage
|
||||
objects. These are:
|
||||
|
||||
@@ -133,14 +133,14 @@ example). If this sounds a bit tricky, don't worry -- it will become clearer in
|
||||
the examples below. Just remember that you will often end up creating two
|
||||
classes when you want a custom field:
|
||||
|
||||
* The first class is the Python object that your users will manipulate.
|
||||
They will assign it to the model attribute, they will read from it for
|
||||
displaying purposes, things like that. This is the ``Hand`` class in our
|
||||
example.
|
||||
* The first class is the Python object that your users will manipulate.
|
||||
They will assign it to the model attribute, they will read from it for
|
||||
displaying purposes, things like that. This is the ``Hand`` class in our
|
||||
example.
|
||||
|
||||
* The second class is the ``Field`` subclass. This is the class that knows
|
||||
how to convert your first class back and forth between its permanent
|
||||
storage form and the Python form.
|
||||
* The second class is the ``Field`` subclass. This is the class that knows
|
||||
how to convert your first class back and forth between its permanent
|
||||
storage form and the Python form.
|
||||
|
||||
Writing a field subclass
|
||||
========================
|
||||
@@ -198,33 +198,33 @@ card values plus their suits; 104 characters in total.
|
||||
The :meth:`~django.db.models.Field.__init__` method takes the following
|
||||
parameters:
|
||||
|
||||
* :attr:`~django.db.models.Field.verbose_name`
|
||||
* :attr:`~django.db.models.Field.name`
|
||||
* :attr:`~django.db.models.Field.primary_key`
|
||||
* :attr:`~django.db.models.Field.max_length`
|
||||
* :attr:`~django.db.models.Field.unique`
|
||||
* :attr:`~django.db.models.Field.blank`
|
||||
* :attr:`~django.db.models.Field.null`
|
||||
* :attr:`~django.db.models.Field.db_index`
|
||||
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
|
||||
:class:`ForeignKey`). For advanced use only.
|
||||
* :attr:`~django.db.models.Field.default`
|
||||
* :attr:`~django.db.models.Field.editable`
|
||||
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
|
||||
not be serialized when the model is passed to Django's :doc:`serializers
|
||||
</topics/serialization>`. Defaults to ``True``.
|
||||
* :attr:`~django.db.models.Field.unique_for_date`
|
||||
* :attr:`~django.db.models.Field.unique_for_month`
|
||||
* :attr:`~django.db.models.Field.unique_for_year`
|
||||
* :attr:`~django.db.models.Field.choices`
|
||||
* :attr:`~django.db.models.Field.help_text`
|
||||
* :attr:`~django.db.models.Field.db_column`
|
||||
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
|
||||
the Oracle backend and only for index creation. You can usually ignore
|
||||
this option.
|
||||
* :attr:`~django.db.models.Field.auto_created`: True if the field was
|
||||
automatically created, as for the `OneToOneField` used by model
|
||||
inheritance. For advanced use only.
|
||||
* :attr:`~django.db.models.Field.verbose_name`
|
||||
* :attr:`~django.db.models.Field.name`
|
||||
* :attr:`~django.db.models.Field.primary_key`
|
||||
* :attr:`~django.db.models.Field.max_length`
|
||||
* :attr:`~django.db.models.Field.unique`
|
||||
* :attr:`~django.db.models.Field.blank`
|
||||
* :attr:`~django.db.models.Field.null`
|
||||
* :attr:`~django.db.models.Field.db_index`
|
||||
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
|
||||
:class:`ForeignKey`). For advanced use only.
|
||||
* :attr:`~django.db.models.Field.default`
|
||||
* :attr:`~django.db.models.Field.editable`
|
||||
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
|
||||
not be serialized when the model is passed to Django's :doc:`serializers
|
||||
</topics/serialization>`. Defaults to ``True``.
|
||||
* :attr:`~django.db.models.Field.unique_for_date`
|
||||
* :attr:`~django.db.models.Field.unique_for_month`
|
||||
* :attr:`~django.db.models.Field.unique_for_year`
|
||||
* :attr:`~django.db.models.Field.choices`
|
||||
* :attr:`~django.db.models.Field.help_text`
|
||||
* :attr:`~django.db.models.Field.db_column`
|
||||
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
|
||||
the Oracle backend and only for index creation. You can usually ignore
|
||||
this option.
|
||||
* :attr:`~django.db.models.Field.auto_created`: True if the field was
|
||||
automatically created, as for the `OneToOneField` used by model
|
||||
inheritance. For advanced use only.
|
||||
|
||||
All of the options without an explanation in the above list have the same
|
||||
meaning they do for normal Django fields. See the :doc:`field documentation
|
||||
@@ -415,11 +415,11 @@ that are more complex than strings, dates, integers or floats, then you'll need
|
||||
to override this method. As a general rule, the method should deal gracefully
|
||||
with any of the following arguments:
|
||||
|
||||
* An instance of the correct type (e.g., ``Hand`` in our ongoing example).
|
||||
* An instance of the correct type (e.g., ``Hand`` in our ongoing example).
|
||||
|
||||
* A string (e.g., from a deserializer).
|
||||
* A string (e.g., from a deserializer).
|
||||
|
||||
* Whatever the database returns for the column type you're using.
|
||||
* Whatever the database returns for the column type you're using.
|
||||
|
||||
In our ``HandField`` class, we're storing the data as a VARCHAR field in the
|
||||
database, so we need to be able to process strings and ``Hand`` instances in
|
||||
@@ -695,19 +695,19 @@ complex conversions between your Python types and your database and
|
||||
serialization formats. Here are a couple of tips to make things go more
|
||||
smoothly:
|
||||
|
||||
1. Look at the existing Django fields (in
|
||||
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
|
||||
a field that's similar to what you want and extend it a little bit,
|
||||
instead of creating an entirely new field from scratch.
|
||||
1. Look at the existing Django fields (in
|
||||
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
|
||||
a field that's similar to what you want and extend it a little bit,
|
||||
instead of creating an entirely new field from scratch.
|
||||
|
||||
2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
|
||||
wrapping up as a field. There are a lot of places where the default
|
||||
behavior of the field code is to call
|
||||
:func:`~django.utils.encoding.force_unicode` on the value. (In our
|
||||
examples in this document, ``value`` would be a ``Hand`` instance, not a
|
||||
``HandField``). So if your :meth:`__unicode__` method automatically
|
||||
converts to the string form of your Python object, you can save yourself
|
||||
a lot of work.
|
||||
2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
|
||||
wrapping up as a field. There are a lot of places where the default
|
||||
behavior of the field code is to call
|
||||
:func:`~django.utils.encoding.force_unicode` on the value. (In our
|
||||
examples in this document, ``value`` would be a ``Hand`` instance, not a
|
||||
``HandField``). So if your :meth:`__unicode__` method automatically
|
||||
converts to the string form of your Python object, you can save yourself
|
||||
a lot of work.
|
||||
|
||||
|
||||
Writing a ``FileField`` subclass
|
||||
@@ -735,14 +735,14 @@ A few suggestions
|
||||
In addition to the above details, there are a few guidelines which can greatly
|
||||
improve the efficiency and readability of the field's code.
|
||||
|
||||
1. The source for Django's own ``ImageField`` (in
|
||||
``django/db/models/fields/files.py``) is a great example of how to
|
||||
subclass ``FileField`` to support a particular type of file, as it
|
||||
incorporates all of the techniques described above.
|
||||
1. The source for Django's own ``ImageField`` (in
|
||||
``django/db/models/fields/files.py``) is a great example of how to
|
||||
subclass ``FileField`` to support a particular type of file, as it
|
||||
incorporates all of the techniques described above.
|
||||
|
||||
2. Cache file attributes wherever possible. Since files may be stored in
|
||||
remote storage systems, retrieving them may cost extra time, or even
|
||||
money, that isn't always necessary. Once a file is retrieved to obtain
|
||||
some data about its content, cache as much of that data as possible to
|
||||
reduce the number of times the file must be retrieved on subsequent
|
||||
calls for that information.
|
||||
2. Cache file attributes wherever possible. Since files may be stored in
|
||||
remote storage systems, retrieving them may cost extra time, or even
|
||||
money, that isn't always necessary. Once a file is retrieved to obtain
|
||||
some data about its content, cache as much of that data as possible to
|
||||
reduce the number of times the file must be retrieved on subsequent
|
||||
calls for that information.
|
||||
|
||||
@@ -77,9 +77,9 @@ Writing custom template filters
|
||||
|
||||
Custom filters are just Python functions that take one or two arguments:
|
||||
|
||||
* The value of the variable (input) -- not necessarily a string.
|
||||
* The value of the argument -- this can have a default value, or be left
|
||||
out altogether.
|
||||
* The value of the variable (input) -- not necessarily a string.
|
||||
* The value of the argument -- this can have a default value, or be left
|
||||
out altogether.
|
||||
|
||||
For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
|
||||
passed the variable ``var`` and the argument ``"bar"``.
|
||||
@@ -124,9 +124,9 @@ your ``Library`` instance, to make it available to Django's template language:
|
||||
|
||||
The ``Library.filter()`` method takes two arguments:
|
||||
|
||||
1. The name of the filter -- a string.
|
||||
2. The compilation function -- a Python function (not the name of the
|
||||
function as a string).
|
||||
1. The name of the filter -- a string.
|
||||
2. The compilation function -- a Python function (not the name of the
|
||||
function as a string).
|
||||
|
||||
You can use ``register.filter()`` as a decorator instead:
|
||||
|
||||
@@ -173,156 +173,156 @@ When writing a custom filter, give some thought to how the filter will interact
|
||||
with Django's auto-escaping behavior. Note that three types of strings can be
|
||||
passed around inside the template code:
|
||||
|
||||
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
|
||||
output, they're escaped if auto-escaping is in effect and presented
|
||||
unchanged, otherwise.
|
||||
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
|
||||
output, they're escaped if auto-escaping is in effect and presented
|
||||
unchanged, otherwise.
|
||||
|
||||
* **Safe strings** are strings that have been marked safe from further
|
||||
escaping at output time. Any necessary escaping has already been done.
|
||||
They're commonly used for output that contains raw HTML that is intended
|
||||
to be interpreted as-is on the client side.
|
||||
* **Safe strings** are strings that have been marked safe from further
|
||||
escaping at output time. Any necessary escaping has already been done.
|
||||
They're commonly used for output that contains raw HTML that is intended
|
||||
to be interpreted as-is on the client side.
|
||||
|
||||
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
|
||||
They share a common base class of ``SafeData``, so you can test
|
||||
for them using code like:
|
||||
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
|
||||
They share a common base class of ``SafeData``, so you can test
|
||||
for them using code like:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: python
|
||||
|
||||
if isinstance(value, SafeData):
|
||||
# Do something with the "safe" string.
|
||||
...
|
||||
if isinstance(value, SafeData):
|
||||
# Do something with the "safe" string.
|
||||
...
|
||||
|
||||
* **Strings marked as "needing escaping"** are *always* escaped on
|
||||
output, regardless of whether they are in an :ttag:`autoescape` block or
|
||||
not. These strings are only escaped once, however, even if auto-escaping
|
||||
applies.
|
||||
* **Strings marked as "needing escaping"** are *always* escaped on
|
||||
output, regardless of whether they are in an :ttag:`autoescape` block or
|
||||
not. These strings are only escaped once, however, even if auto-escaping
|
||||
applies.
|
||||
|
||||
Internally, these strings are of type ``EscapeString`` or
|
||||
``EscapeUnicode``. Generally you don't have to worry about these; they
|
||||
exist for the implementation of the :tfilter:`escape` filter.
|
||||
Internally, these strings are of type ``EscapeString`` or
|
||||
``EscapeUnicode``. Generally you don't have to worry about these; they
|
||||
exist for the implementation of the :tfilter:`escape` filter.
|
||||
|
||||
Template filter code falls into one of two situations:
|
||||
|
||||
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
|
||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||
this case, you can let Django take care of all the auto-escaping
|
||||
handling for you. All you need to do is put the ``is_safe`` attribute on
|
||||
your filter function and set it to ``True``, like so:
|
||||
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
|
||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||
this case, you can let Django take care of all the auto-escaping
|
||||
handling for you. All you need to do is put the ``is_safe`` attribute on
|
||||
your filter function and set it to ``True``, like so:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: python
|
||||
|
||||
@register.filter
|
||||
def myfilter(value):
|
||||
return value
|
||||
myfilter.is_safe = True
|
||||
@register.filter
|
||||
def myfilter(value):
|
||||
return value
|
||||
myfilter.is_safe = True
|
||||
|
||||
This attribute tells Django that if a "safe" string is passed into your
|
||||
filter, the result will still be "safe" and if a non-safe string is
|
||||
passed in, Django will automatically escape it, if necessary.
|
||||
This attribute tells Django that if a "safe" string is passed into your
|
||||
filter, the result will still be "safe" and if a non-safe string is
|
||||
passed in, Django will automatically escape it, if necessary.
|
||||
|
||||
You can think of this as meaning "this filter is safe -- it doesn't
|
||||
introduce any possibility of unsafe HTML."
|
||||
You can think of this as meaning "this filter is safe -- it doesn't
|
||||
introduce any possibility of unsafe HTML."
|
||||
|
||||
The reason ``is_safe`` is necessary is because there are plenty of
|
||||
normal string operations that will turn a ``SafeData`` object back into
|
||||
a normal ``str`` or ``unicode`` object and, rather than try to catch
|
||||
them all, which would be very difficult, Django repairs the damage after
|
||||
the filter has completed.
|
||||
The reason ``is_safe`` is necessary is because there are plenty of
|
||||
normal string operations that will turn a ``SafeData`` object back into
|
||||
a normal ``str`` or ``unicode`` object and, rather than try to catch
|
||||
them all, which would be very difficult, Django repairs the damage after
|
||||
the filter has completed.
|
||||
|
||||
For example, suppose you have a filter that adds the string ``xx`` to
|
||||
the end of any input. Since this introduces no dangerous HTML characters
|
||||
to the result (aside from any that were already present), you should
|
||||
mark your filter with ``is_safe``:
|
||||
For example, suppose you have a filter that adds the string ``xx`` to
|
||||
the end of any input. Since this introduces no dangerous HTML characters
|
||||
to the result (aside from any that were already present), you should
|
||||
mark your filter with ``is_safe``:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: python
|
||||
|
||||
@register.filter
|
||||
def add_xx(value):
|
||||
return '%sxx' % value
|
||||
add_xx.is_safe = True
|
||||
@register.filter
|
||||
def add_xx(value):
|
||||
return '%sxx' % value
|
||||
add_xx.is_safe = True
|
||||
|
||||
When this filter is used in a template where auto-escaping is enabled,
|
||||
Django will escape the output whenever the input is not already marked
|
||||
as "safe".
|
||||
When this filter is used in a template where auto-escaping is enabled,
|
||||
Django will escape the output whenever the input is not already marked
|
||||
as "safe".
|
||||
|
||||
By default, ``is_safe`` defaults to ``False``, and you can omit it from
|
||||
any filters where it isn't required.
|
||||
By default, ``is_safe`` defaults to ``False``, and you can omit it from
|
||||
any filters where it isn't required.
|
||||
|
||||
Be careful when deciding if your filter really does leave safe strings
|
||||
as safe. If you're *removing* characters, you might inadvertently leave
|
||||
unbalanced HTML tags or entities in the result. For example, removing a
|
||||
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
|
||||
be escaped on output to avoid causing problems. Similarly, removing a
|
||||
semicolon (``;``) can turn ``&`` 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.
|
||||
Be careful when deciding if your filter really does leave safe strings
|
||||
as safe. If you're *removing* characters, you might inadvertently leave
|
||||
unbalanced HTML tags or entities in the result. For example, removing a
|
||||
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
|
||||
be escaped on output to avoid causing problems. Similarly, removing a
|
||||
semicolon (``;``) can turn ``&`` 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.
|
||||
|
||||
Marking a filter ``is_safe`` will coerce the filter's return value to
|
||||
a string. If your filter should return a boolean or other non-string
|
||||
value, marking it ``is_safe`` will probably have unintended
|
||||
consequences (such as converting a boolean False to the string
|
||||
'False').
|
||||
Marking a filter ``is_safe`` will coerce the filter's return value to
|
||||
a string. If your filter should return a boolean or other non-string
|
||||
value, marking it ``is_safe`` will probably have unintended
|
||||
consequences (such as converting a boolean False to the string
|
||||
'False').
|
||||
|
||||
2. Alternatively, your filter code can manually take care of any necessary
|
||||
escaping. This is necessary when you're introducing new HTML markup into
|
||||
the result. You want to mark the output as safe from further
|
||||
escaping so that your HTML markup isn't escaped further, so you'll need
|
||||
to handle the input yourself.
|
||||
2. Alternatively, your filter code can manually take care of any necessary
|
||||
escaping. This is necessary when you're introducing new HTML markup into
|
||||
the result. You want to mark the output as safe from further
|
||||
escaping so that your HTML markup isn't escaped further, so you'll need
|
||||
to handle the input yourself.
|
||||
|
||||
To mark the output as a safe string, use
|
||||
:func:`django.utils.safestring.mark_safe`.
|
||||
To mark the output as a safe string, use
|
||||
:func:`django.utils.safestring.mark_safe`.
|
||||
|
||||
Be careful, though. You need to do more than just mark the output as
|
||||
safe. You need to ensure it really *is* safe, and what you do depends on
|
||||
whether auto-escaping is in effect. The idea is to write filters than
|
||||
can operate in templates where auto-escaping is either on or off in
|
||||
order to make things easier for your template authors.
|
||||
Be careful, though. You need to do more than just mark the output as
|
||||
safe. You need to ensure it really *is* safe, and what you do depends on
|
||||
whether auto-escaping is in effect. The idea is to write filters than
|
||||
can operate in templates where auto-escaping is either on or off in
|
||||
order to make things easier for your template authors.
|
||||
|
||||
In order for your filter to know the current auto-escaping state, set
|
||||
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
|
||||
don't specify this attribute, it defaults to ``False``). This attribute
|
||||
tells Django that your filter function wants to be passed an extra
|
||||
keyword argument, called ``autoescape``, that is ``True`` if
|
||||
auto-escaping is in effect and ``False`` otherwise.
|
||||
In order for your filter to know the current auto-escaping state, set
|
||||
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
|
||||
don't specify this attribute, it defaults to ``False``). This attribute
|
||||
tells Django that your filter function wants to be passed an extra
|
||||
keyword argument, called ``autoescape``, that is ``True`` if
|
||||
auto-escaping is in effect and ``False`` otherwise.
|
||||
|
||||
For example, let's write a filter that emphasizes the first character of
|
||||
a string:
|
||||
For example, let's write a filter that emphasizes the first character of
|
||||
a string:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: python
|
||||
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
def initial_letter_filter(text, autoescape=None):
|
||||
first, other = text[0], text[1:]
|
||||
if autoescape:
|
||||
esc = conditional_escape
|
||||
else:
|
||||
esc = lambda x: x
|
||||
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
|
||||
return mark_safe(result)
|
||||
initial_letter_filter.needs_autoescape = True
|
||||
def initial_letter_filter(text, autoescape=None):
|
||||
first, other = text[0], text[1:]
|
||||
if autoescape:
|
||||
esc = conditional_escape
|
||||
else:
|
||||
esc = lambda x: x
|
||||
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
|
||||
return mark_safe(result)
|
||||
initial_letter_filter.needs_autoescape = True
|
||||
|
||||
The ``needs_autoescape`` attribute on the filter function and the
|
||||
``autoescape`` keyword argument mean that our function will know whether
|
||||
automatic escaping is in effect when the filter is called. We use
|
||||
``autoescape`` to decide whether the input data needs to be passed
|
||||
through ``django.utils.html.conditional_escape`` or not. (In the latter
|
||||
case, we just use the identity function as the "escape" function.) The
|
||||
``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
The ``needs_autoescape`` attribute on the filter function and the
|
||||
``autoescape`` keyword argument mean that our function will know whether
|
||||
automatic escaping is in effect when the filter is called. We use
|
||||
``autoescape`` to decide whether the input data needs to be passed
|
||||
through ``django.utils.html.conditional_escape`` or not. (In the latter
|
||||
case, we just use the identity function as the "escape" function.) The
|
||||
``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
escaping.
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
escaping.
|
||||
|
||||
There's no need to worry about the ``is_safe`` attribute in this case
|
||||
(although including it wouldn't hurt anything). Whenever you manually
|
||||
handle the auto-escaping issues and return a safe string, the
|
||||
``is_safe`` attribute won't change anything either way.
|
||||
There's no need to worry about the ``is_safe`` attribute in this case
|
||||
(although including it wouldn't hurt anything). Whenever you manually
|
||||
handle the auto-escaping issues and return a safe string, the
|
||||
``is_safe`` attribute won't change anything either way.
|
||||
|
||||
Writing custom template tags
|
||||
----------------------------
|
||||
@@ -381,37 +381,37 @@ object:
|
||||
|
||||
Notes:
|
||||
|
||||
* ``parser`` is the template parser object. We don't need it in this
|
||||
example.
|
||||
* ``parser`` is the template parser object. We don't need it in this
|
||||
example.
|
||||
|
||||
* ``token.contents`` is a string of the raw contents of the tag. In our
|
||||
example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
|
||||
* ``token.contents`` is a string of the raw contents of the tag. In our
|
||||
example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
|
||||
|
||||
* The ``token.split_contents()`` method separates the arguments on spaces
|
||||
while keeping quoted strings together. The more straightforward
|
||||
``token.contents.split()`` wouldn't be as robust, as it would naively
|
||||
split on *all* spaces, including those within quoted strings. It's a good
|
||||
idea to always use ``token.split_contents()``.
|
||||
* The ``token.split_contents()`` method separates the arguments on spaces
|
||||
while keeping quoted strings together. The more straightforward
|
||||
``token.contents.split()`` wouldn't be as robust, as it would naively
|
||||
split on *all* spaces, including those within quoted strings. It's a good
|
||||
idea to always use ``token.split_contents()``.
|
||||
|
||||
* This function is responsible for raising
|
||||
``django.template.TemplateSyntaxError``, with helpful messages, for
|
||||
any syntax error.
|
||||
* This function is responsible for raising
|
||||
``django.template.TemplateSyntaxError``, with helpful messages, for
|
||||
any syntax error.
|
||||
|
||||
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
|
||||
Don't hard-code the tag's name in your error messages, because that
|
||||
couples the tag's name to your function. ``token.contents.split()[0]``
|
||||
will ''always'' be the name of your tag -- even when the tag has no
|
||||
arguments.
|
||||
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
|
||||
Don't hard-code the tag's name in your error messages, because that
|
||||
couples the tag's name to your function. ``token.contents.split()[0]``
|
||||
will ''always'' be the name of your tag -- even when the tag has no
|
||||
arguments.
|
||||
|
||||
* The function returns a ``CurrentTimeNode`` with everything the node needs
|
||||
to know about this tag. In this case, it just passes the argument --
|
||||
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
|
||||
template tag are removed in ``format_string[1:-1]``.
|
||||
* The function returns a ``CurrentTimeNode`` with everything the node needs
|
||||
to know about this tag. In this case, it just passes the argument --
|
||||
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
|
||||
template tag are removed in ``format_string[1:-1]``.
|
||||
|
||||
* The parsing is very low-level. The Django developers have experimented
|
||||
with writing small frameworks on top of this parsing system, using
|
||||
techniques such as EBNF grammars, but those experiments made the template
|
||||
engine too slow. It's low-level because that's fastest.
|
||||
* The parsing is very low-level. The Django developers have experimented
|
||||
with writing small frameworks on top of this parsing system, using
|
||||
techniques such as EBNF grammars, but those experiments made the template
|
||||
engine too slow. It's low-level because that's fastest.
|
||||
|
||||
Writing the renderer
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -433,14 +433,14 @@ Continuing the above example, we need to define ``CurrentTimeNode``:
|
||||
|
||||
Notes:
|
||||
|
||||
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
|
||||
Always pass any options/parameters/arguments to a ``Node`` via its
|
||||
``__init__()``.
|
||||
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
|
||||
Always pass any options/parameters/arguments to a ``Node`` via its
|
||||
``__init__()``.
|
||||
|
||||
* The ``render()`` method is where the work actually happens.
|
||||
* The ``render()`` method is where the work actually happens.
|
||||
|
||||
* ``render()`` should never raise ``TemplateSyntaxError`` or any other
|
||||
exception. It should fail silently, just as template filters should.
|
||||
* ``render()`` should never raise ``TemplateSyntaxError`` or any other
|
||||
exception. It should fail silently, just as template filters should.
|
||||
|
||||
Ultimately, this decoupling of compilation and rendering results in an
|
||||
efficient template system, because a template can render multiple contexts
|
||||
@@ -525,14 +525,14 @@ A naive implementation of ``CycleNode`` might look something like this:
|
||||
But, suppose we have two templates rendering the template snippet from above at
|
||||
the same time:
|
||||
|
||||
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
|
||||
returns 'row1'
|
||||
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
|
||||
returns 'row2'
|
||||
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
|
||||
returns 'row1'
|
||||
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
|
||||
returns 'row2'
|
||||
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
|
||||
returns 'row1'
|
||||
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
|
||||
returns 'row2'
|
||||
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
|
||||
returns 'row1'
|
||||
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
|
||||
returns 'row2'
|
||||
|
||||
The CycleNode is iterating, but it's iterating globally. As far as Thread 1
|
||||
and Thread 2 are concerned, it's always returning the same value. This is
|
||||
@@ -584,10 +584,10 @@ in "Writing custom template filters" above. Example:
|
||||
|
||||
The ``tag()`` method takes two arguments:
|
||||
|
||||
1. The name of the template tag -- a string. If this is left out, the
|
||||
name of the compilation function will be used.
|
||||
2. The compilation function -- a Python function (not the name of the
|
||||
function as a string).
|
||||
1. The name of the template tag -- a string. If this is left out, the
|
||||
name of the compilation function will be used.
|
||||
2. The compilation function -- a Python function (not the name of the
|
||||
function as a string).
|
||||
|
||||
As with filter registration, it is also possible to use this as a decorator:
|
||||
|
||||
@@ -623,12 +623,12 @@ tag format that date-time:
|
||||
|
||||
Initially, ``token.split_contents()`` will return three values:
|
||||
|
||||
1. The tag name ``format_time``.
|
||||
2. The string ``"blog_entry.date_updated"`` (without the surrounding
|
||||
quotes).
|
||||
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
|
||||
``split_contents()`` will include the leading and trailing quotes for
|
||||
string literals like this.
|
||||
1. The tag name ``format_time``.
|
||||
2. The string ``"blog_entry.date_updated"`` (without the surrounding
|
||||
quotes).
|
||||
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
|
||||
``split_contents()`` will include the leading and trailing quotes for
|
||||
string literals like this.
|
||||
|
||||
Now your tag should begin to look like this:
|
||||
|
||||
@@ -706,12 +706,12 @@ The decorator syntax also works:
|
||||
|
||||
A few things to note about the ``simple_tag`` helper function:
|
||||
|
||||
* Checking for the required number of arguments, etc., has already been
|
||||
done by the time our function is called, so we don't need to do that.
|
||||
* The quotes around the argument (if any) have already been stripped away,
|
||||
so we just receive a plain string.
|
||||
* If the argument was a template variable, our function is passed the
|
||||
current value of the variable, not the variable itself.
|
||||
* Checking for the required number of arguments, etc., has already been
|
||||
done by the time our function is called, so we don't need to do that.
|
||||
* The quotes around the argument (if any) have already been stripped away,
|
||||
so we just receive a plain string.
|
||||
* If the argument was a template variable, our function is passed the
|
||||
current value of the variable, not the variable itself.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
|
||||
@@ -168,9 +168,9 @@ Once you've got that set up, point Apache at your Django FastCGI instance by
|
||||
editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two
|
||||
things:
|
||||
|
||||
* Use the ``FastCGIExternalServer`` directive to specify the location of
|
||||
your FastCGI server.
|
||||
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
|
||||
* Use the ``FastCGIExternalServer`` directive to specify the location of
|
||||
your FastCGI server.
|
||||
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
|
||||
|
||||
.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
|
||||
|
||||
|
||||
@@ -240,11 +240,11 @@ server you choose.
|
||||
We recommend using a separate Web server -- i.e., one that's not also running
|
||||
Django -- for serving media. Here are some good choices:
|
||||
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* A stripped-down version of Apache_
|
||||
* Cherokee_
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* A stripped-down version of Apache_
|
||||
* Cherokee_
|
||||
|
||||
If, however, you have no option but to serve media or static files on the
|
||||
same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python
|
||||
@@ -299,11 +299,11 @@ Django distribution.
|
||||
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
|
||||
the admin files, but here are two other approaches:
|
||||
|
||||
1. Create a symbolic link to the admin static files from within your
|
||||
document root.
|
||||
1. Create a symbolic link to the admin static files from within your
|
||||
document root.
|
||||
|
||||
2. Or, copy the admin static files so that they live within your Apache
|
||||
document root.
|
||||
2. Or, copy the admin static files so that they live within your Apache
|
||||
document root.
|
||||
|
||||
Using "eggs" with mod_python
|
||||
============================
|
||||
@@ -362,15 +362,15 @@ If you get a segmentation fault
|
||||
If Apache causes a segmentation fault, there are two probable causes, neither
|
||||
of which has to do with Django itself.
|
||||
|
||||
1. It may be because your Python code is importing the "pyexpat" module,
|
||||
which may conflict with the version embedded in Apache. For full
|
||||
information, see `Expat Causing Apache Crash`_.
|
||||
1. It may be because your Python code is importing the "pyexpat" module,
|
||||
which may conflict with the version embedded in Apache. For full
|
||||
information, see `Expat Causing Apache Crash`_.
|
||||
|
||||
2. It may be because you're running mod_python and mod_php in the same
|
||||
Apache instance, with MySQL as your database backend. In some cases,
|
||||
this causes a known mod_python issue due to version conflicts in PHP and
|
||||
the Python MySQL backend. There's full information in the
|
||||
`mod_python FAQ entry`_.
|
||||
2. It may be because you're running mod_python and mod_php in the same
|
||||
Apache instance, with MySQL as your database backend. In some cases,
|
||||
this causes a known mod_python issue due to version conflicts in PHP and
|
||||
the Python MySQL backend. There's full information in the
|
||||
`mod_python FAQ entry`_.
|
||||
|
||||
If you continue to have problems setting up mod_python, a good thing to do is
|
||||
get a barebones mod_python site working, without the Django framework. This is
|
||||
|
||||
@@ -64,11 +64,11 @@ server you choose.
|
||||
We recommend using a separate Web server -- i.e., one that's not also running
|
||||
Django -- for serving media. Here are some good choices:
|
||||
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* A stripped-down version of Apache_
|
||||
* Cherokee_
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* A stripped-down version of Apache_
|
||||
* Cherokee_
|
||||
|
||||
If, however, you have no option but to serve media files on the same Apache
|
||||
``VirtualHost`` as Django, you can set up Apache to serve some URLs as
|
||||
@@ -131,11 +131,11 @@ Django distribution.
|
||||
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
|
||||
the admin files, but here are two other approaches:
|
||||
|
||||
1. Create a symbolic link to the admin static files from within your
|
||||
document root.
|
||||
1. Create a symbolic link to the admin static files from within your
|
||||
document root.
|
||||
|
||||
2. Or, copy the admin static files so that they live within your Apache
|
||||
document root.
|
||||
2. Or, copy the admin static files so that they live within your Apache
|
||||
document root.
|
||||
|
||||
Details
|
||||
=======
|
||||
|
||||
@@ -56,12 +56,12 @@ setting.
|
||||
Django can also be configured to email errors about broken links (404 "page
|
||||
not found" errors). Django sends emails about 404 errors when:
|
||||
|
||||
* :setting:`DEBUG` is ``False``
|
||||
* :setting:`DEBUG` is ``False``
|
||||
|
||||
* :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
|
||||
* :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
|
||||
|
||||
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
|
||||
(which it does by default).
|
||||
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
|
||||
(which it does by default).
|
||||
|
||||
If those conditions are met, Django will email the users listed in the
|
||||
:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
|
||||
@@ -144,18 +144,16 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
|
||||
If a function (either a view or any regular callback) in your code uses
|
||||
local variables susceptible to contain sensitive information, you may
|
||||
prevent the values of those variables from being included in error reports
|
||||
using the ``sensitive_variables`` decorator:
|
||||
using the ``sensitive_variables`` decorator::
|
||||
|
||||
.. code-block:: python
|
||||
from django.views.decorators.debug import sensitive_variables
|
||||
|
||||
from django.views.decorators.debug import sensitive_variables
|
||||
|
||||
@sensitive_variables('user', 'pw', 'cc')
|
||||
def process_info(user):
|
||||
pw = user.pass_word
|
||||
cc = user.credit_card_number
|
||||
name = user.name
|
||||
...
|
||||
@sensitive_variables('user', 'pw', 'cc')
|
||||
def process_info(user):
|
||||
pw = user.pass_word
|
||||
cc = user.credit_card_number
|
||||
name = user.name
|
||||
...
|
||||
|
||||
In the above example, the values for the ``user``, ``pw`` and ``cc``
|
||||
variables will be hidden and replaced with stars (`**********`) in the
|
||||
@@ -163,13 +161,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
|
||||
disclosed.
|
||||
|
||||
To systematically hide all local variables of a function from error logs,
|
||||
do not provide any argument to the ``sensitive_variables`` decorator:
|
||||
do not provide any argument to the ``sensitive_variables`` decorator::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@sensitive_variables()
|
||||
def my_function():
|
||||
...
|
||||
@sensitive_variables()
|
||||
def my_function():
|
||||
...
|
||||
|
||||
.. function:: sensitive_post_parameters(*parameters)
|
||||
|
||||
@@ -177,19 +173,17 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
|
||||
:attr:`POST parameters<HttpRequest.POST>` susceptible to contain sensitive
|
||||
information, you may prevent the values of those parameters from being
|
||||
included in the error reports using the ``sensitive_post_parameters``
|
||||
decorator:
|
||||
decorator::
|
||||
|
||||
.. code-block:: python
|
||||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
|
||||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
|
||||
@sensitive_post_parameters('pass_word', 'credit_card_number')
|
||||
def record_user_profile(request):
|
||||
UserProfile.create(user=request.user,
|
||||
password=request.POST['pass_word'],
|
||||
credit_card=request.POST['credit_card_number'],
|
||||
name=request.POST['name'])
|
||||
...
|
||||
@sensitive_post_parameters('pass_word', 'credit_card_number')
|
||||
def record_user_profile(request):
|
||||
UserProfile.create(user=request.user,
|
||||
password=request.POST['pass_word'],
|
||||
credit_card=request.POST['credit_card_number'],
|
||||
name=request.POST['name'])
|
||||
...
|
||||
|
||||
In the above example, the values for the ``pass_word`` and
|
||||
``credit_card_number`` POST parameters will be hidden and replaced with
|
||||
@@ -197,13 +191,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
|
||||
reports, whereas the value of the ``name`` parameter will be disclosed.
|
||||
|
||||
To systematically hide all POST parameters of a request in error reports,
|
||||
do not provide any argument to the ``sensitive_post_parameters`` decorator:
|
||||
do not provide any argument to the ``sensitive_post_parameters`` decorator::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@sensitive_post_parameters()
|
||||
def my_view(request):
|
||||
...
|
||||
@sensitive_post_parameters()
|
||||
def my_view(request):
|
||||
...
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -231,22 +223,18 @@ decorators' annotations to replace the corresponding values with stars
|
||||
(`**********`) when the error reports are produced. If you wish to override or
|
||||
customize this default behavior for your entire site, you need to define your
|
||||
own filter class and tell Django to use it via the
|
||||
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting:
|
||||
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
|
||||
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
|
||||
|
||||
You may also control in a more granular way which filter to use within any
|
||||
given view by setting the ``HttpRequest``'s ``exception_reporter_filter``
|
||||
attribute:
|
||||
attribute::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def my_view(request):
|
||||
if request.user.is_authenticated():
|
||||
request.exception_reporter_filter = CustomExceptionReporterFilter()
|
||||
...
|
||||
def my_view(request):
|
||||
if request.user.is_authenticated():
|
||||
request.exception_reporter_filter = CustomExceptionReporterFilter()
|
||||
...
|
||||
|
||||
Your custom filter class needs to inherit from
|
||||
:class:`django.views.debug.SafeExceptionReporterFilter` and may override the
|
||||
|
||||
@@ -10,16 +10,16 @@ the order in which it examines the different file paths to load the compiled
|
||||
:term:`message files <message file>` (``.mo``) and the precedence of multiple
|
||||
translations for the same literal:
|
||||
|
||||
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
|
||||
precedence, with the ones appearing first having higher precedence than
|
||||
the ones appearing later.
|
||||
2. Then, it looks for and uses if it exists a ``locale`` directory in each
|
||||
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
|
||||
appearing first have higher precedence than the ones appearing later.
|
||||
3. Then, it looks for a ``locale`` directory in the project directory, or
|
||||
more accurately, in the directory containing your settings file.
|
||||
4. Finally, the Django-provided base translation in ``django/conf/locale``
|
||||
is used as a fallback.
|
||||
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
|
||||
precedence, with the ones appearing first having higher precedence than
|
||||
the ones appearing later.
|
||||
2. Then, it looks for and uses if it exists a ``locale`` directory in each
|
||||
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
|
||||
appearing first have higher precedence than the ones appearing later.
|
||||
3. Then, it looks for a ``locale`` directory in the project directory, or
|
||||
more accurately, in the directory containing your settings file.
|
||||
4. Finally, the Django-provided base translation in ``django/conf/locale``
|
||||
is used as a fallback.
|
||||
|
||||
.. deprecated:: 1.3
|
||||
Lookup in the ``locale`` subdirectory of the directory containing your
|
||||
@@ -55,12 +55,12 @@ message file specific to the project you are composing. The choice is yours.
|
||||
|
||||
All message file repositories are structured the same way. They are:
|
||||
|
||||
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
|
||||
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
|
||||
deprecated, see above.
|
||||
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
|
||||
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
|
||||
deprecated, see above.
|
||||
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
|
||||
To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
|
||||
tool. You only need to be in the same directory where the ``locale/`` directory
|
||||
|
||||
@@ -64,10 +64,10 @@ Differences with Django on Jython
|
||||
At this point, Django on Jython should behave nearly identically to Django
|
||||
running on standard Python. However, are a few differences to keep in mind:
|
||||
|
||||
* Remember to use the ``jython`` command instead of ``python``. The
|
||||
documentation uses ``python`` for consistency, but if you're using Jython
|
||||
you'll want to mentally replace ``python`` with ``jython`` every time it
|
||||
occurs.
|
||||
* Remember to use the ``jython`` command instead of ``python``. The
|
||||
documentation uses ``python`` for consistency, but if you're using Jython
|
||||
you'll want to mentally replace ``python`` with ``jython`` every time it
|
||||
occurs.
|
||||
|
||||
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
|
||||
instead of ``PYTHONPATH``.
|
||||
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
|
||||
instead of ``PYTHONPATH``.
|
||||
|
||||
@@ -20,12 +20,12 @@ what the name of the database is. Do that by editing the :setting:`DATABASES`
|
||||
setting and assigning values to the following keys for the ``'default'``
|
||||
connection:
|
||||
|
||||
* :setting:`NAME`
|
||||
* :setting:`ENGINE`
|
||||
* :setting:`USER`
|
||||
* :setting:`PASSWORD`
|
||||
* :setting:`HOST`
|
||||
* :setting:`PORT`
|
||||
* :setting:`NAME`
|
||||
* :setting:`ENGINE`
|
||||
* :setting:`USER`
|
||||
* :setting:`PASSWORD`
|
||||
* :setting:`HOST`
|
||||
* :setting:`PORT`
|
||||
|
||||
Auto-generate the models
|
||||
========================
|
||||
|
||||
@@ -32,27 +32,27 @@ Here's an example::
|
||||
The code and comments should be self-explanatory, but a few things deserve a
|
||||
mention:
|
||||
|
||||
* The response gets a special MIME type, :mimetype:`text/csv`. This tells
|
||||
browsers that the document is a CSV file, rather than an HTML file. If
|
||||
you leave this off, browsers will probably interpret the output as HTML,
|
||||
which will result in ugly, scary gobbledygook in the browser window.
|
||||
* The response gets a special MIME type, :mimetype:`text/csv`. This tells
|
||||
browsers that the document is a CSV file, rather than an HTML file. If
|
||||
you leave this off, browsers will probably interpret the output as HTML,
|
||||
which will result in ugly, scary gobbledygook in the browser window.
|
||||
|
||||
* The response gets an additional ``Content-Disposition`` header, which
|
||||
contains the name of the CSV file. This filename is arbitrary; call it
|
||||
whatever you want. It'll be used by browsers in the "Save as..."
|
||||
dialogue, etc.
|
||||
* The response gets an additional ``Content-Disposition`` header, which
|
||||
contains the name of the CSV file. This filename is arbitrary; call it
|
||||
whatever you want. It'll be used by browsers in the "Save as..."
|
||||
dialogue, etc.
|
||||
|
||||
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
|
||||
first argument to ``csv.writer``. The ``csv.writer`` function expects a
|
||||
file-like object, and :class:`~django.http.HttpResponse` objects fit the
|
||||
bill.
|
||||
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
|
||||
first argument to ``csv.writer``. The ``csv.writer`` function expects a
|
||||
file-like object, and :class:`~django.http.HttpResponse` objects fit the
|
||||
bill.
|
||||
|
||||
* For each row in your CSV file, call ``writer.writerow``, passing it an
|
||||
iterable object such as a list or tuple.
|
||||
* For each row in your CSV file, call ``writer.writerow``, passing it an
|
||||
iterable object such as a list or tuple.
|
||||
|
||||
* The CSV module takes care of quoting for you, so you don't have to worry
|
||||
about escaping strings with quotes or commas in them. Just pass
|
||||
``writerow()`` your raw strings, and it'll do the right thing.
|
||||
* The CSV module takes care of quoting for you, so you don't have to worry
|
||||
about escaping strings with quotes or commas in them. Just pass
|
||||
``writerow()`` your raw strings, and it'll do the right thing.
|
||||
|
||||
Handling Unicode
|
||||
~~~~~~~~~~~~~~~~
|
||||
@@ -62,13 +62,13 @@ Unicode internally this means strings read from sources such as
|
||||
:class:`~django.http.HttpRequest` are potentially problematic. There are a few
|
||||
options for handling this:
|
||||
|
||||
* Manually encode all Unicode objects to a compatible encoding.
|
||||
* Manually encode all Unicode objects to a compatible encoding.
|
||||
|
||||
* Use the ``UnicodeWriter`` class provided in the `csv module's examples
|
||||
section`_.
|
||||
* Use the ``UnicodeWriter`` class provided in the `csv module's examples
|
||||
section`_.
|
||||
|
||||
* Use the `python-unicodecsv module`_, which aims to be a drop-in
|
||||
replacement for :mod:`csv` that gracefully handles Unicode.
|
||||
* Use the `python-unicodecsv module`_, which aims to be a drop-in
|
||||
replacement for :mod:`csv` that gracefully handles Unicode.
|
||||
|
||||
For more information, see the Python documentation of the :mod:`csv` module.
|
||||
|
||||
|
||||
@@ -63,36 +63,36 @@ Here's a "Hello World" example::
|
||||
The code and comments should be self-explanatory, but a few things deserve a
|
||||
mention:
|
||||
|
||||
* The response gets a special MIME type, :mimetype:`application/pdf`. This
|
||||
tells browsers that the document is a PDF file, rather than an HTML file.
|
||||
If you leave this off, browsers will probably interpret the output as
|
||||
HTML, which would result in ugly, scary gobbledygook in the browser
|
||||
window.
|
||||
* The response gets a special MIME type, :mimetype:`application/pdf`. This
|
||||
tells browsers that the document is a PDF file, rather than an HTML file.
|
||||
If you leave this off, browsers will probably interpret the output as
|
||||
HTML, which would result in ugly, scary gobbledygook in the browser
|
||||
window.
|
||||
|
||||
* The response gets an additional ``Content-Disposition`` header, which
|
||||
contains the name of the PDF file. This filename is arbitrary: Call it
|
||||
whatever you want. It'll be used by browsers in the "Save as..."
|
||||
dialogue, etc.
|
||||
* The response gets an additional ``Content-Disposition`` header, which
|
||||
contains the name of the PDF file. This filename is arbitrary: Call it
|
||||
whatever you want. It'll be used by browsers in the "Save as..."
|
||||
dialogue, etc.
|
||||
|
||||
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
|
||||
example. This forces Web browsers to pop-up a dialog box
|
||||
prompting/confirming how to handle the document even if a default is set
|
||||
on the machine. If you leave off ``'attachment;'``, browsers will handle
|
||||
the PDF using whatever program/plugin they've been configured to use for
|
||||
PDFs. Here's what that code would look like::
|
||||
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
|
||||
example. This forces Web browsers to pop-up a dialog box
|
||||
prompting/confirming how to handle the document even if a default is set
|
||||
on the machine. If you leave off ``'attachment;'``, browsers will handle
|
||||
the PDF using whatever program/plugin they've been configured to use for
|
||||
PDFs. Here's what that code would look like::
|
||||
|
||||
response['Content-Disposition'] = 'filename=somefilename.pdf'
|
||||
response['Content-Disposition'] = 'filename=somefilename.pdf'
|
||||
|
||||
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
|
||||
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
|
||||
file-like object, and :class:`~django.http.HttpResponse` objects fit the
|
||||
bill.
|
||||
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
|
||||
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
|
||||
file-like object, and :class:`~django.http.HttpResponse` objects fit the
|
||||
bill.
|
||||
|
||||
* Note that all subsequent PDF-generation methods are called on the PDF
|
||||
object (in this case, ``p``) -- not on ``response``.
|
||||
* Note that all subsequent PDF-generation methods are called on the PDF
|
||||
object (in this case, ``p``) -- not on ``response``.
|
||||
|
||||
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
|
||||
file.
|
||||
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
|
||||
file.
|
||||
|
||||
Complex PDFs
|
||||
============
|
||||
@@ -137,13 +137,13 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`::
|
||||
Further resources
|
||||
=================
|
||||
|
||||
* PDFlib_ is another PDF-generation library that has Python bindings. To
|
||||
use it with Django, just use the same concepts explained in this article.
|
||||
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
|
||||
an example of how to integrate Pisa with Django.
|
||||
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
|
||||
doesn't have a Python interface, but you can escape out to the shell
|
||||
using ``system`` or ``popen`` and retrieve the output in Python.
|
||||
* PDFlib_ is another PDF-generation library that has Python bindings. To
|
||||
use it with Django, just use the same concepts explained in this article.
|
||||
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
|
||||
an example of how to integrate Pisa with Django.
|
||||
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
|
||||
doesn't have a Python interface, but you can escape out to the shell
|
||||
using ``system`` or ``popen`` and retrieve the output in Python.
|
||||
|
||||
.. _PDFlib: http://www.pdflib.org/
|
||||
.. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/
|
||||
|
||||
@@ -345,11 +345,11 @@ Serving the app and your static files from the same server
|
||||
If you want to serve your static files from the same server that's already
|
||||
serving your site, the basic outline gets modified to look something like:
|
||||
|
||||
* Push your code up to the deployment server.
|
||||
* On the server, run :djadmin:`collectstatic` to copy all the static files
|
||||
into :setting:`STATIC_ROOT`.
|
||||
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
|
||||
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
|
||||
* Push your code up to the deployment server.
|
||||
* On the server, run :djadmin:`collectstatic` to copy all the static files
|
||||
into :setting:`STATIC_ROOT`.
|
||||
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
|
||||
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
|
||||
|
||||
You'll probably want to automate this process, especially if you've got
|
||||
multiple web servers. There's any number of ways to do this automation, but
|
||||
@@ -386,11 +386,11 @@ Most larger Django apps use a separate Web server -- i.e., one that's not also
|
||||
running Django -- for serving static files. This server often runs a different
|
||||
type of web server -- faster but less full-featured. Some good choices are:
|
||||
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* Cherokee_
|
||||
* A stripped-down version of Apache_
|
||||
* lighttpd_
|
||||
* Nginx_
|
||||
* TUX_
|
||||
* Cherokee_
|
||||
* A stripped-down version of Apache_
|
||||
|
||||
.. _lighttpd: http://www.lighttpd.net/
|
||||
.. _Nginx: http://wiki.nginx.org/Main
|
||||
@@ -404,11 +404,11 @@ server's respective documentation for instructions.
|
||||
Since your static file server won't be running Django, you'll need to modify
|
||||
the deployment strategy to look something like:
|
||||
|
||||
* When your static files change, run :djadmin:`collectstatic` locally.
|
||||
* Push your local :setting:`STATIC_ROOT` up to the static file server
|
||||
into the directory that's being served. ``rsync`` is a good
|
||||
choice for this step since it only needs to transfer the
|
||||
bits of static files that have changed.
|
||||
* When your static files change, run :djadmin:`collectstatic` locally.
|
||||
* Push your local :setting:`STATIC_ROOT` up to the static file server
|
||||
into the directory that's being served. ``rsync`` is a good
|
||||
choice for this step since it only needs to transfer the
|
||||
bits of static files that have changed.
|
||||
|
||||
Here's how this might look in a fabfile::
|
||||
|
||||
@@ -479,27 +479,27 @@ Upgrading from ``django-staticfiles``
|
||||
you're upgrading from `django-staticfiles`_ older than 1.0 (e.g. 0.3.4) to
|
||||
``django.contrib.staticfiles``, you'll need to make a few changes:
|
||||
|
||||
* Application files should now live in a ``static`` directory in each app
|
||||
(`django-staticfiles`_ used the name ``media``, which was slightly
|
||||
confusing).
|
||||
* Application files should now live in a ``static`` directory in each app
|
||||
(`django-staticfiles`_ used the name ``media``, which was slightly
|
||||
confusing).
|
||||
|
||||
* The management commands ``build_static`` and ``resolve_static`` are now
|
||||
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
|
||||
* The management commands ``build_static`` and ``resolve_static`` are now
|
||||
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
|
||||
|
||||
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
|
||||
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
|
||||
removed.
|
||||
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
|
||||
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
|
||||
removed.
|
||||
|
||||
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
|
||||
new :setting:`STATICFILES_FINDERS`.
|
||||
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
|
||||
new :setting:`STATICFILES_FINDERS`.
|
||||
|
||||
* The default for :setting:`STATICFILES_STORAGE` was renamed from
|
||||
``staticfiles.storage.StaticFileStorage`` to
|
||||
``staticfiles.storage.StaticFilesStorage``
|
||||
* The default for :setting:`STATICFILES_STORAGE` was renamed from
|
||||
``staticfiles.storage.StaticFileStorage`` to
|
||||
``staticfiles.storage.StaticFilesStorage``
|
||||
|
||||
* If using :ref:`runserver<staticfiles-runserver>` for local development
|
||||
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
|
||||
anything to your URLconf for serving static files in development.
|
||||
* If using :ref:`runserver<staticfiles-runserver>` for local development
|
||||
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
|
||||
anything to your URLconf for serving static files in development.
|
||||
|
||||
Learn more
|
||||
==========
|
||||
|
||||
Reference in New Issue
Block a user