1
0
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:
Luke Plant
2011-10-14 00:12:01 +00:00
parent 5109ac3709
commit d1e5c55258
129 changed files with 5708 additions and 5740 deletions

View File

@@ -14,12 +14,12 @@ dealing with Apache, you can configuring Apache to authenticate against Django's
:doc:`authentication system </topics/auth>` directly. For example, you
could:
* Serve static/media files directly from Apache only to authenticated users.
* Serve static/media files directly from Apache only to authenticated users.
* Authenticate access to a Subversion_ repository against Django users with
a certain permission.
* Authenticate access to a Subversion_ repository against Django users with
a certain permission.
* Allow certain users to connect to a WebDAV share created with mod_dav_.
* Allow certain users to connect to a WebDAV share created with mod_dav_.
.. _Subversion: http://subversion.tigris.org/
.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
@@ -93,29 +93,29 @@ By default, the authentication handler will limit access to the ``/example/``
location to users marked as staff members. You can use a set of
``PythonOption`` directives to modify this behavior:
================================ =========================================
``PythonOption`` Explanation
================================ =========================================
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
those with the ``is_staff`` flag set)
will be allowed.
================================ =========================================
``PythonOption`` Explanation
================================ =========================================
``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
those with the ``is_staff`` flag set)
will be allowed.
Defaults to ``on``.
Defaults to ``on``.
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
those with the ``is_superuser`` flag set)
will be allowed.
``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
those with the ``is_superuser`` flag set)
will be allowed.
Defaults to ``off``.
Defaults to ``off``.
``DjangoPermissionName`` The name of a permission to require for
access. See :ref:`custom permissions
<custom-permissions>` for more
information.
``DjangoPermissionName`` The name of a permission to require for
access. See :ref:`custom permissions
<custom-permissions>` for more
information.
By default no specific permission will be
required.
================================ =========================================
By default no specific permission will be
required.
================================ =========================================
Note that sometimes ``SetEnv`` doesn't play well in this mod_python
configuration, for reasons unknown. If you're having problems getting

View File

@@ -37,11 +37,11 @@ You'll need to follow these steps:
Your custom storage system may override any of the storage methods explained in
:doc:`/ref/files/storage`, but you **must** implement the following methods:
* :meth:`Storage.delete`
* :meth:`Storage.exists`
* :meth:`Storage.listdir`
* :meth:`Storage.size`
* :meth:`Storage.url`
* :meth:`Storage.delete`
* :meth:`Storage.exists`
* :meth:`Storage.listdir`
* :meth:`Storage.size`
* :meth:`Storage.url`
You'll also usually want to use hooks specifically designed for custom storage
objects. These are:

View File

@@ -133,14 +133,14 @@ example). If this sounds a bit tricky, don't worry -- it will become clearer in
the examples below. Just remember that you will often end up creating two
classes when you want a custom field:
* The first class is the Python object that your users will manipulate.
They will assign it to the model attribute, they will read from it for
displaying purposes, things like that. This is the ``Hand`` class in our
example.
* The first class is the Python object that your users will manipulate.
They will assign it to the model attribute, they will read from it for
displaying purposes, things like that. This is the ``Hand`` class in our
example.
* The second class is the ``Field`` subclass. This is the class that knows
how to convert your first class back and forth between its permanent
storage form and the Python form.
* The second class is the ``Field`` subclass. This is the class that knows
how to convert your first class back and forth between its permanent
storage form and the Python form.
Writing a field subclass
========================
@@ -198,33 +198,33 @@ card values plus their suits; 104 characters in total.
The :meth:`~django.db.models.Field.__init__` method takes the following
parameters:
* :attr:`~django.db.models.Field.verbose_name`
* :attr:`~django.db.models.Field.name`
* :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.Field.max_length`
* :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index`
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
:class:`ForeignKey`). For advanced use only.
* :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable`
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
not be serialized when the model is passed to Django's :doc:`serializers
</topics/serialization>`. Defaults to ``True``.
* :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
the Oracle backend and only for index creation. You can usually ignore
this option.
* :attr:`~django.db.models.Field.auto_created`: True if the field was
automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only.
* :attr:`~django.db.models.Field.verbose_name`
* :attr:`~django.db.models.Field.name`
* :attr:`~django.db.models.Field.primary_key`
* :attr:`~django.db.models.Field.max_length`
* :attr:`~django.db.models.Field.unique`
* :attr:`~django.db.models.Field.blank`
* :attr:`~django.db.models.Field.null`
* :attr:`~django.db.models.Field.db_index`
* :attr:`~django.db.models.Field.rel`: Used for related fields (like
:class:`ForeignKey`). For advanced use only.
* :attr:`~django.db.models.Field.default`
* :attr:`~django.db.models.Field.editable`
* :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
not be serialized when the model is passed to Django's :doc:`serializers
</topics/serialization>`. Defaults to ``True``.
* :attr:`~django.db.models.Field.unique_for_date`
* :attr:`~django.db.models.Field.unique_for_month`
* :attr:`~django.db.models.Field.unique_for_year`
* :attr:`~django.db.models.Field.choices`
* :attr:`~django.db.models.Field.help_text`
* :attr:`~django.db.models.Field.db_column`
* :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
the Oracle backend and only for index creation. You can usually ignore
this option.
* :attr:`~django.db.models.Field.auto_created`: True if the field was
automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only.
All of the options without an explanation in the above list have the same
meaning they do for normal Django fields. See the :doc:`field documentation
@@ -415,11 +415,11 @@ that are more complex than strings, dates, integers or floats, then you'll need
to override this method. As a general rule, the method should deal gracefully
with any of the following arguments:
* An instance of the correct type (e.g., ``Hand`` in our ongoing example).
* An instance of the correct type (e.g., ``Hand`` in our ongoing example).
* A string (e.g., from a deserializer).
* A string (e.g., from a deserializer).
* Whatever the database returns for the column type you're using.
* Whatever the database returns for the column type you're using.
In our ``HandField`` class, we're storing the data as a VARCHAR field in the
database, so we need to be able to process strings and ``Hand`` instances in
@@ -695,19 +695,19 @@ complex conversions between your Python types and your database and
serialization formats. Here are a couple of tips to make things go more
smoothly:
1. Look at the existing Django fields (in
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
a field that's similar to what you want and extend it a little bit,
instead of creating an entirely new field from scratch.
1. Look at the existing Django fields (in
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
a field that's similar to what you want and extend it a little bit,
instead of creating an entirely new field from scratch.
2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
wrapping up as a field. There are a lot of places where the default
behavior of the field code is to call
:func:`~django.utils.encoding.force_unicode` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your :meth:`__unicode__` method automatically
converts to the string form of your Python object, you can save yourself
a lot of work.
2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
wrapping up as a field. There are a lot of places where the default
behavior of the field code is to call
:func:`~django.utils.encoding.force_unicode` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your :meth:`__unicode__` method automatically
converts to the string form of your Python object, you can save yourself
a lot of work.
Writing a ``FileField`` subclass
@@ -735,14 +735,14 @@ A few suggestions
In addition to the above details, there are a few guidelines which can greatly
improve the efficiency and readability of the field's code.
1. The source for Django's own ``ImageField`` (in
``django/db/models/fields/files.py``) is a great example of how to
subclass ``FileField`` to support a particular type of file, as it
incorporates all of the techniques described above.
1. The source for Django's own ``ImageField`` (in
``django/db/models/fields/files.py``) is a great example of how to
subclass ``FileField`` to support a particular type of file, as it
incorporates all of the techniques described above.
2. Cache file attributes wherever possible. Since files may be stored in
remote storage systems, retrieving them may cost extra time, or even
money, that isn't always necessary. Once a file is retrieved to obtain
some data about its content, cache as much of that data as possible to
reduce the number of times the file must be retrieved on subsequent
calls for that information.
2. Cache file attributes wherever possible. Since files may be stored in
remote storage systems, retrieving them may cost extra time, or even
money, that isn't always necessary. Once a file is retrieved to obtain
some data about its content, cache as much of that data as possible to
reduce the number of times the file must be retrieved on subsequent
calls for that information.

View File

@@ -77,9 +77,9 @@ Writing custom template filters
Custom filters are just Python functions that take one or two arguments:
* The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left
out altogether.
* The value of the variable (input) -- not necessarily a string.
* The value of the argument -- this can have a default value, or be left
out altogether.
For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
passed the variable ``var`` and the argument ``"bar"``.
@@ -124,9 +124,9 @@ your ``Library`` instance, to make it available to Django's template language:
The ``Library.filter()`` method takes two arguments:
1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the
function as a string).
1. The name of the filter -- a string.
2. The compilation function -- a Python function (not the name of the
function as a string).
You can use ``register.filter()`` as a decorator instead:
@@ -173,156 +173,156 @@ When writing a custom filter, give some thought to how the filter will interact
with Django's auto-escaping behavior. Note that three types of strings can be
passed around inside the template code:
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
output, they're escaped if auto-escaping is in effect and presented
unchanged, otherwise.
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
output, they're escaped if auto-escaping is in effect and presented
unchanged, otherwise.
* **Safe strings** are strings that have been marked safe from further
escaping at output time. Any necessary escaping has already been done.
They're commonly used for output that contains raw HTML that is intended
to be interpreted as-is on the client side.
* **Safe strings** are strings that have been marked safe from further
escaping at output time. Any necessary escaping has already been done.
They're commonly used for output that contains raw HTML that is intended
to be interpreted as-is on the client side.
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
They share a common base class of ``SafeData``, so you can test
for them using code like:
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
They share a common base class of ``SafeData``, so you can test
for them using code like:
.. code-block:: python
.. code-block:: python
if isinstance(value, SafeData):
# Do something with the "safe" string.
...
if isinstance(value, SafeData):
# Do something with the "safe" string.
...
* **Strings marked as "needing escaping"** are *always* escaped on
output, regardless of whether they are in an :ttag:`autoescape` block or
not. These strings are only escaped once, however, even if auto-escaping
applies.
* **Strings marked as "needing escaping"** are *always* escaped on
output, regardless of whether they are in an :ttag:`autoescape` block or
not. These strings are only escaped once, however, even if auto-escaping
applies.
Internally, these strings are of type ``EscapeString`` or
``EscapeUnicode``. Generally you don't have to worry about these; they
exist for the implementation of the :tfilter:`escape` filter.
Internally, these strings are of type ``EscapeString`` or
``EscapeUnicode``. Generally you don't have to worry about these; they
exist for the implementation of the :tfilter:`escape` filter.
Template filter code falls into one of two situations:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In
this case, you can let Django take care of all the auto-escaping
handling for you. All you need to do is put the ``is_safe`` attribute on
your filter function and set it to ``True``, like so:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In
this case, you can let Django take care of all the auto-escaping
handling for you. All you need to do is put the ``is_safe`` attribute on
your filter function and set it to ``True``, like so:
.. code-block:: python
.. code-block:: python
@register.filter
def myfilter(value):
return value
myfilter.is_safe = True
@register.filter
def myfilter(value):
return value
myfilter.is_safe = True
This attribute tells Django that if a "safe" string is passed into your
filter, the result will still be "safe" and if a non-safe string is
passed in, Django will automatically escape it, if necessary.
This attribute tells Django that if a "safe" string is passed into your
filter, the result will still be "safe" and if a non-safe string is
passed in, Django will automatically escape it, if necessary.
You can think of this as meaning "this filter is safe -- it doesn't
introduce any possibility of unsafe HTML."
You can think of this as meaning "this filter is safe -- it doesn't
introduce any possibility of unsafe HTML."
The reason ``is_safe`` is necessary is because there are plenty of
normal string operations that will turn a ``SafeData`` object back into
a normal ``str`` or ``unicode`` object and, rather than try to catch
them all, which would be very difficult, Django repairs the damage after
the filter has completed.
The reason ``is_safe`` is necessary is because there are plenty of
normal string operations that will turn a ``SafeData`` object back into
a normal ``str`` or ``unicode`` object and, rather than try to catch
them all, which would be very difficult, Django repairs the damage after
the filter has completed.
For example, suppose you have a filter that adds the string ``xx`` to
the end of any input. Since this introduces no dangerous HTML characters
to the result (aside from any that were already present), you should
mark your filter with ``is_safe``:
For example, suppose you have a filter that adds the string ``xx`` to
the end of any input. Since this introduces no dangerous HTML characters
to the result (aside from any that were already present), you should
mark your filter with ``is_safe``:
.. code-block:: python
.. code-block:: python
@register.filter
def add_xx(value):
return '%sxx' % value
add_xx.is_safe = True
@register.filter
def add_xx(value):
return '%sxx' % value
add_xx.is_safe = True
When this filter is used in a template where auto-escaping is enabled,
Django will escape the output whenever the input is not already marked
as "safe".
When this filter is used in a template where auto-escaping is enabled,
Django will escape the output whenever the input is not already marked
as "safe".
By default, ``is_safe`` defaults to ``False``, and you can omit it from
any filters where it isn't required.
By default, ``is_safe`` defaults to ``False``, and you can omit it from
any filters where it isn't required.
Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave
unbalanced HTML tags or entities in the result. For example, removing a
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
be escaped on output to avoid causing problems. Similarly, removing a
semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
valid entity and thus needs further escaping. Most cases won't be nearly
this tricky, but keep an eye out for any problems like that when
reviewing your code.
Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave
unbalanced HTML tags or entities in the result. For example, removing a
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
be escaped on output to avoid causing problems. Similarly, removing a
semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
valid entity and thus needs further escaping. Most cases won't be nearly
this tricky, but keep an eye out for any problems like that when
reviewing your code.
Marking a filter ``is_safe`` will coerce the filter's return value to
a string. If your filter should return a boolean or other non-string
value, marking it ``is_safe`` will probably have unintended
consequences (such as converting a boolean False to the string
'False').
Marking a filter ``is_safe`` will coerce the filter's return value to
a string. If your filter should return a boolean or other non-string
value, marking it ``is_safe`` will probably have unintended
consequences (such as converting a boolean False to the string
'False').
2. Alternatively, your filter code can manually take care of any necessary
escaping. This is necessary when you're introducing new HTML markup into
the result. You want to mark the output as safe from further
escaping so that your HTML markup isn't escaped further, so you'll need
to handle the input yourself.
2. Alternatively, your filter code can manually take care of any necessary
escaping. This is necessary when you're introducing new HTML markup into
the result. You want to mark the output as safe from further
escaping so that your HTML markup isn't escaped further, so you'll need
to handle the input yourself.
To mark the output as a safe string, use
:func:`django.utils.safestring.mark_safe`.
To mark the output as a safe string, use
:func:`django.utils.safestring.mark_safe`.
Be careful, though. You need to do more than just mark the output as
safe. You need to ensure it really *is* safe, and what you do depends on
whether auto-escaping is in effect. The idea is to write filters than
can operate in templates where auto-escaping is either on or off in
order to make things easier for your template authors.
Be careful, though. You need to do more than just mark the output as
safe. You need to ensure it really *is* safe, and what you do depends on
whether auto-escaping is in effect. The idea is to write filters than
can operate in templates where auto-escaping is either on or off in
order to make things easier for your template authors.
In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise.
In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise.
For example, let's write a filter that emphasizes the first character of
a string:
For example, let's write a filter that emphasizes the first character of
a string:
.. code-block:: python
.. code-block:: python
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:]
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result)
initial_letter_filter.needs_autoescape = True
def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:]
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result)
initial_letter_filter.needs_autoescape = True
The ``needs_autoescape`` attribute on the filter function and the
``autoescape`` keyword argument mean that our function will know whether
automatic escaping is in effect when the filter is called. We use
``autoescape`` to decide whether the input data needs to be passed
through ``django.utils.html.conditional_escape`` or not. (In the latter
case, we just use the identity function as the "escape" function.) The
``conditional_escape()`` function is like ``escape()`` except it only
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
instance is passed to ``conditional_escape()``, the data is returned
unchanged.
The ``needs_autoescape`` attribute on the filter function and the
``autoescape`` keyword argument mean that our function will know whether
automatic escaping is in effect when the filter is called. We use
``autoescape`` to decide whether the input data needs to be passed
through ``django.utils.html.conditional_escape`` or not. (In the latter
case, we just use the identity function as the "escape" function.) The
``conditional_escape()`` function is like ``escape()`` except it only
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
instance is passed to ``conditional_escape()``, the data is returned
unchanged.
Finally, in the above example, we remember to mark the result as safe
so that our HTML is inserted directly into the template without further
escaping.
Finally, in the above example, we remember to mark the result as safe
so that our HTML is inserted directly into the template without further
escaping.
There's no need to worry about the ``is_safe`` attribute in this case
(although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the
``is_safe`` attribute won't change anything either way.
There's no need to worry about the ``is_safe`` attribute in this case
(although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the
``is_safe`` attribute won't change anything either way.
Writing custom template tags
----------------------------
@@ -381,37 +381,37 @@ object:
Notes:
* ``parser`` is the template parser object. We don't need it in this
example.
* ``parser`` is the template parser object. We don't need it in this
example.
* ``token.contents`` is a string of the raw contents of the tag. In our
example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
* ``token.contents`` is a string of the raw contents of the tag. In our
example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
* The ``token.split_contents()`` method separates the arguments on spaces
while keeping quoted strings together. The more straightforward
``token.contents.split()`` wouldn't be as robust, as it would naively
split on *all* spaces, including those within quoted strings. It's a good
idea to always use ``token.split_contents()``.
* The ``token.split_contents()`` method separates the arguments on spaces
while keeping quoted strings together. The more straightforward
``token.contents.split()`` wouldn't be as robust, as it would naively
split on *all* spaces, including those within quoted strings. It's a good
idea to always use ``token.split_contents()``.
* This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for
any syntax error.
* This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for
any syntax error.
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
Don't hard-code the tag's name in your error messages, because that
couples the tag's name to your function. ``token.contents.split()[0]``
will ''always'' be the name of your tag -- even when the tag has no
arguments.
* The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
Don't hard-code the tag's name in your error messages, because that
couples the tag's name to your function. ``token.contents.split()[0]``
will ''always'' be the name of your tag -- even when the tag has no
arguments.
* The function returns a ``CurrentTimeNode`` with everything the node needs
to know about this tag. In this case, it just passes the argument --
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
template tag are removed in ``format_string[1:-1]``.
* The function returns a ``CurrentTimeNode`` with everything the node needs
to know about this tag. In this case, it just passes the argument --
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
template tag are removed in ``format_string[1:-1]``.
* The parsing is very low-level. The Django developers have experimented
with writing small frameworks on top of this parsing system, using
techniques such as EBNF grammars, but those experiments made the template
engine too slow. It's low-level because that's fastest.
* The parsing is very low-level. The Django developers have experimented
with writing small frameworks on top of this parsing system, using
techniques such as EBNF grammars, but those experiments made the template
engine too slow. It's low-level because that's fastest.
Writing the renderer
~~~~~~~~~~~~~~~~~~~~
@@ -433,14 +433,14 @@ Continuing the above example, we need to define ``CurrentTimeNode``:
Notes:
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
Always pass any options/parameters/arguments to a ``Node`` via its
``__init__()``.
* ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
Always pass any options/parameters/arguments to a ``Node`` via its
``__init__()``.
* The ``render()`` method is where the work actually happens.
* The ``render()`` method is where the work actually happens.
* ``render()`` should never raise ``TemplateSyntaxError`` or any other
exception. It should fail silently, just as template filters should.
* ``render()`` should never raise ``TemplateSyntaxError`` or any other
exception. It should fail silently, just as template filters should.
Ultimately, this decoupling of compilation and rendering results in an
efficient template system, because a template can render multiple contexts
@@ -525,14 +525,14 @@ A naive implementation of ``CycleNode`` might look something like this:
But, suppose we have two templates rendering the template snippet from above at
the same time:
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
returns 'row2'
1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
returns 'row1'
2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
returns 'row2'
3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
returns 'row1'
4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
returns 'row2'
The CycleNode is iterating, but it's iterating globally. As far as Thread 1
and Thread 2 are concerned, it's always returning the same value. This is
@@ -584,10 +584,10 @@ in "Writing custom template filters" above. Example:
The ``tag()`` method takes two arguments:
1. The name of the template tag -- a string. If this is left out, the
name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the
function as a string).
1. The name of the template tag -- a string. If this is left out, the
name of the compilation function will be used.
2. The compilation function -- a Python function (not the name of the
function as a string).
As with filter registration, it is also possible to use this as a decorator:
@@ -623,12 +623,12 @@ tag format that date-time:
Initially, ``token.split_contents()`` will return three values:
1. The tag name ``format_time``.
2. The string ``"blog_entry.date_updated"`` (without the surrounding
quotes).
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
``split_contents()`` will include the leading and trailing quotes for
string literals like this.
1. The tag name ``format_time``.
2. The string ``"blog_entry.date_updated"`` (without the surrounding
quotes).
3. The formatting string ``"%Y-%m-%d %I:%M %p"``. The return value from
``split_contents()`` will include the leading and trailing quotes for
string literals like this.
Now your tag should begin to look like this:
@@ -706,12 +706,12 @@ The decorator syntax also works:
A few things to note about the ``simple_tag`` helper function:
* Checking for the required number of arguments, etc., has already been
done by the time our function is called, so we don't need to do that.
* The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string.
* If the argument was a template variable, our function is passed the
current value of the variable, not the variable itself.
* Checking for the required number of arguments, etc., has already been
done by the time our function is called, so we don't need to do that.
* The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string.
* If the argument was a template variable, our function is passed the
current value of the variable, not the variable itself.
.. versionadded:: 1.3

View File

@@ -168,9 +168,9 @@ Once you've got that set up, point Apache at your Django FastCGI instance by
editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two
things:
* Use the ``FastCGIExternalServer`` directive to specify the location of
your FastCGI server.
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
* Use the ``FastCGIExternalServer`` directive to specify the location of
your FastCGI server.
* Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

View File

@@ -240,11 +240,11 @@ server you choose.
We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices:
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
If, however, you have no option but to serve media or static files on the
same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python
@@ -299,11 +299,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your
document root.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
Using "eggs" with mod_python
============================
@@ -362,15 +362,15 @@ If you get a segmentation fault
If Apache causes a segmentation fault, there are two probable causes, neither
of which has to do with Django itself.
1. It may be because your Python code is importing the "pyexpat" module,
which may conflict with the version embedded in Apache. For full
information, see `Expat Causing Apache Crash`_.
1. It may be because your Python code is importing the "pyexpat" module,
which may conflict with the version embedded in Apache. For full
information, see `Expat Causing Apache Crash`_.
2. It may be because you're running mod_python and mod_php in the same
Apache instance, with MySQL as your database backend. In some cases,
this causes a known mod_python issue due to version conflicts in PHP and
the Python MySQL backend. There's full information in the
`mod_python FAQ entry`_.
2. It may be because you're running mod_python and mod_php in the same
Apache instance, with MySQL as your database backend. In some cases,
this causes a known mod_python issue due to version conflicts in PHP and
the Python MySQL backend. There's full information in the
`mod_python FAQ entry`_.
If you continue to have problems setting up mod_python, a good thing to do is
get a barebones mod_python site working, without the Django framework. This is

View File

@@ -64,11 +64,11 @@ server you choose.
We recommend using a separate Web server -- i.e., one that's not also running
Django -- for serving media. Here are some good choices:
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
* lighttpd_
* Nginx_
* TUX_
* A stripped-down version of Apache_
* Cherokee_
If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, you can set up Apache to serve some URLs as
@@ -131,11 +131,11 @@ Django distribution.
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle
the admin files, but here are two other approaches:
1. Create a symbolic link to the admin static files from within your
document root.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
2. Or, copy the admin static files so that they live within your Apache
document root.
Details
=======

View File

@@ -56,12 +56,12 @@ setting.
Django can also be configured to email errors about broken links (404 "page
not found" errors). Django sends emails about 404 errors when:
* :setting:`DEBUG` is ``False``
* :setting:`DEBUG` is ``False``
* :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
* :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
(which it does by default).
* Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
(which it does by default).
If those conditions are met, Django will email the users listed in the
:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
@@ -144,18 +144,16 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
If a function (either a view or any regular callback) in your code uses
local variables susceptible to contain sensitive information, you may
prevent the values of those variables from being included in error reports
using the ``sensitive_variables`` decorator:
using the ``sensitive_variables`` decorator::
.. code-block:: python
from django.views.decorators.debug import sensitive_variables
from django.views.decorators.debug import sensitive_variables
@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
pw = user.pass_word
cc = user.credit_card_number
name = user.name
...
@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
pw = user.pass_word
cc = user.credit_card_number
name = user.name
...
In the above example, the values for the ``user``, ``pw`` and ``cc``
variables will be hidden and replaced with stars (`**********`) in the
@@ -163,13 +161,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
disclosed.
To systematically hide all local variables of a function from error logs,
do not provide any argument to the ``sensitive_variables`` decorator:
do not provide any argument to the ``sensitive_variables`` decorator::
.. code-block:: python
@sensitive_variables()
def my_function():
...
@sensitive_variables()
def my_function():
...
.. function:: sensitive_post_parameters(*parameters)
@@ -177,19 +173,17 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
:attr:`POST parameters<HttpRequest.POST>` susceptible to contain sensitive
information, you may prevent the values of those parameters from being
included in the error reports using the ``sensitive_post_parameters``
decorator:
decorator::
.. code-block:: python
from django.views.decorators.debug import sensitive_post_parameters
from django.views.decorators.debug import sensitive_post_parameters
@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
UserProfile.create(user=request.user,
password=request.POST['pass_word'],
credit_card=request.POST['credit_card_number'],
name=request.POST['name'])
...
@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
UserProfile.create(user=request.user,
password=request.POST['pass_word'],
credit_card=request.POST['credit_card_number'],
name=request.POST['name'])
...
In the above example, the values for the ``pass_word`` and
``credit_card_number`` POST parameters will be hidden and replaced with
@@ -197,13 +191,11 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
reports, whereas the value of the ``name`` parameter will be disclosed.
To systematically hide all POST parameters of a request in error reports,
do not provide any argument to the ``sensitive_post_parameters`` decorator:
do not provide any argument to the ``sensitive_post_parameters`` decorator::
.. code-block:: python
@sensitive_post_parameters()
def my_view(request):
...
@sensitive_post_parameters()
def my_view(request):
...
.. note::
@@ -231,22 +223,18 @@ decorators' annotations to replace the corresponding values with stars
(`**********`) when the error reports are produced. If you wish to override or
customize this default behavior for your entire site, you need to define your
own filter class and tell Django to use it via the
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting:
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` setting::
.. code-block:: python
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
You may also control in a more granular way which filter to use within any
given view by setting the ``HttpRequest``'s ``exception_reporter_filter``
attribute:
attribute::
.. code-block:: python
def my_view(request):
if request.user.is_authenticated():
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
def my_view(request):
if request.user.is_authenticated():
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
Your custom filter class needs to inherit from
:class:`django.views.debug.SafeExceptionReporterFilter` and may override the

View File

@@ -10,16 +10,16 @@ the order in which it examines the different file paths to load the compiled
:term:`message files <message file>` (``.mo``) and the precedence of multiple
translations for the same literal:
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
precedence, with the ones appearing first having higher precedence than
the ones appearing later.
2. Then, it looks for and uses if it exists a ``locale`` directory in each
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or
more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale``
is used as a fallback.
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
precedence, with the ones appearing first having higher precedence than
the ones appearing later.
2. Then, it looks for and uses if it exists a ``locale`` directory in each
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or
more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale``
is used as a fallback.
.. deprecated:: 1.3
Lookup in the ``locale`` subdirectory of the directory containing your
@@ -55,12 +55,12 @@ message file specific to the project you are composing. The choice is yours.
All message file repositories are structured the same way. They are:
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above.
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above.
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
tool. You only need to be in the same directory where the ``locale/`` directory

View File

@@ -64,10 +64,10 @@ Differences with Django on Jython
At this point, Django on Jython should behave nearly identically to Django
running on standard Python. However, are a few differences to keep in mind:
* Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it
occurs.
* Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it
occurs.
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
instead of ``PYTHONPATH``.
* Similarly, you'll need to use the ``JYTHONPATH`` environment variable
instead of ``PYTHONPATH``.

View File

@@ -20,12 +20,12 @@ what the name of the database is. Do that by editing the :setting:`DATABASES`
setting and assigning values to the following keys for the ``'default'``
connection:
* :setting:`NAME`
* :setting:`ENGINE`
* :setting:`USER`
* :setting:`PASSWORD`
* :setting:`HOST`
* :setting:`PORT`
* :setting:`NAME`
* :setting:`ENGINE`
* :setting:`USER`
* :setting:`PASSWORD`
* :setting:`HOST`
* :setting:`PORT`
Auto-generate the models
========================

View File

@@ -32,27 +32,27 @@ Here's an example::
The code and comments should be self-explanatory, but a few things deserve a
mention:
* The response gets a special MIME type, :mimetype:`text/csv`. This tells
browsers that the document is a CSV file, rather than an HTML file. If
you leave this off, browsers will probably interpret the output as HTML,
which will result in ugly, scary gobbledygook in the browser window.
* The response gets a special MIME type, :mimetype:`text/csv`. This tells
browsers that the document is a CSV file, rather than an HTML file. If
you leave this off, browsers will probably interpret the output as HTML,
which will result in ugly, scary gobbledygook in the browser window.
* The response gets an additional ``Content-Disposition`` header, which
contains the name of the CSV file. This filename is arbitrary; call it
whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc.
* The response gets an additional ``Content-Disposition`` header, which
contains the name of the CSV file. This filename is arbitrary; call it
whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc.
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
first argument to ``csv.writer``. The ``csv.writer`` function expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
first argument to ``csv.writer``. The ``csv.writer`` function expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* For each row in your CSV file, call ``writer.writerow``, passing it an
iterable object such as a list or tuple.
* For each row in your CSV file, call ``writer.writerow``, passing it an
iterable object such as a list or tuple.
* The CSV module takes care of quoting for you, so you don't have to worry
about escaping strings with quotes or commas in them. Just pass
``writerow()`` your raw strings, and it'll do the right thing.
* The CSV module takes care of quoting for you, so you don't have to worry
about escaping strings with quotes or commas in them. Just pass
``writerow()`` your raw strings, and it'll do the right thing.
Handling Unicode
~~~~~~~~~~~~~~~~
@@ -62,13 +62,13 @@ Unicode internally this means strings read from sources such as
:class:`~django.http.HttpRequest` are potentially problematic. There are a few
options for handling this:
* Manually encode all Unicode objects to a compatible encoding.
* Manually encode all Unicode objects to a compatible encoding.
* Use the ``UnicodeWriter`` class provided in the `csv module's examples
section`_.
* Use the ``UnicodeWriter`` class provided in the `csv module's examples
section`_.
* Use the `python-unicodecsv module`_, which aims to be a drop-in
replacement for :mod:`csv` that gracefully handles Unicode.
* Use the `python-unicodecsv module`_, which aims to be a drop-in
replacement for :mod:`csv` that gracefully handles Unicode.
For more information, see the Python documentation of the :mod:`csv` module.

View File

@@ -63,36 +63,36 @@ Here's a "Hello World" example::
The code and comments should be self-explanatory, but a few things deserve a
mention:
* The response gets a special MIME type, :mimetype:`application/pdf`. This
tells browsers that the document is a PDF file, rather than an HTML file.
If you leave this off, browsers will probably interpret the output as
HTML, which would result in ugly, scary gobbledygook in the browser
window.
* The response gets a special MIME type, :mimetype:`application/pdf`. This
tells browsers that the document is a PDF file, rather than an HTML file.
If you leave this off, browsers will probably interpret the output as
HTML, which would result in ugly, scary gobbledygook in the browser
window.
* The response gets an additional ``Content-Disposition`` header, which
contains the name of the PDF file. This filename is arbitrary: Call it
whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc.
* The response gets an additional ``Content-Disposition`` header, which
contains the name of the PDF file. This filename is arbitrary: Call it
whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc.
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
example. This forces Web browsers to pop-up a dialog box
prompting/confirming how to handle the document even if a default is set
on the machine. If you leave off ``'attachment;'``, browsers will handle
the PDF using whatever program/plugin they've been configured to use for
PDFs. Here's what that code would look like::
* The ``Content-Disposition`` header starts with ``'attachment; '`` in this
example. This forces Web browsers to pop-up a dialog box
prompting/confirming how to handle the document even if a default is set
on the machine. If you leave off ``'attachment;'``, browsers will handle
the PDF using whatever program/plugin they've been configured to use for
PDFs. Here's what that code would look like::
response['Content-Disposition'] = 'filename=somefilename.pdf'
response['Content-Disposition'] = 'filename=somefilename.pdf'
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and :class:`~django.http.HttpResponse` objects fit the
bill.
* Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``.
* Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file.
Complex PDFs
============
@@ -137,13 +137,13 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`::
Further resources
=================
* PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python.
* PDFlib_ is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.
* `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.
* HTMLdoc_ is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using ``system`` or ``popen`` and retrieve the output in Python.
.. _PDFlib: http://www.pdflib.org/
.. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/

View File

@@ -345,11 +345,11 @@ Serving the app and your static files from the same server
If you want to serve your static files from the same server that's already
serving your site, the basic outline gets modified to look something like:
* Push your code up to the deployment server.
* On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
* Push your code up to the deployment server.
* On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
You'll probably want to automate this process, especially if you've got
multiple web servers. There's any number of ways to do this automation, but
@@ -386,11 +386,11 @@ Most larger Django apps use a separate Web server -- i.e., one that's not also
running Django -- for serving static files. This server often runs a different
type of web server -- faster but less full-featured. Some good choices are:
* lighttpd_
* Nginx_
* TUX_
* Cherokee_
* A stripped-down version of Apache_
* lighttpd_
* Nginx_
* TUX_
* Cherokee_
* A stripped-down version of Apache_
.. _lighttpd: http://www.lighttpd.net/
.. _Nginx: http://wiki.nginx.org/Main
@@ -404,11 +404,11 @@ server's respective documentation for instructions.
Since your static file server won't be running Django, you'll need to modify
the deployment strategy to look something like:
* When your static files change, run :djadmin:`collectstatic` locally.
* Push your local :setting:`STATIC_ROOT` up to the static file server
into the directory that's being served. ``rsync`` is a good
choice for this step since it only needs to transfer the
bits of static files that have changed.
* When your static files change, run :djadmin:`collectstatic` locally.
* Push your local :setting:`STATIC_ROOT` up to the static file server
into the directory that's being served. ``rsync`` is a good
choice for this step since it only needs to transfer the
bits of static files that have changed.
Here's how this might look in a fabfile::
@@ -479,27 +479,27 @@ Upgrading from ``django-staticfiles``
you're upgrading from `django-staticfiles`_ older than 1.0 (e.g. 0.3.4) to
``django.contrib.staticfiles``, you'll need to make a few changes:
* Application files should now live in a ``static`` directory in each app
(`django-staticfiles`_ used the name ``media``, which was slightly
confusing).
* Application files should now live in a ``static`` directory in each app
(`django-staticfiles`_ used the name ``media``, which was slightly
confusing).
* The management commands ``build_static`` and ``resolve_static`` are now
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
* The management commands ``build_static`` and ``resolve_static`` are now
called :djadmin:`collectstatic` and :djadmin:`findstatic`.
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
removed.
* The settings ``STATICFILES_PREPEND_LABEL_APPS``,
``STATICFILES_MEDIA_DIRNAMES`` and ``STATICFILES_EXCLUDED_APPS`` were
removed.
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
new :setting:`STATICFILES_FINDERS`.
* The setting ``STATICFILES_RESOLVERS`` was removed, and replaced by the
new :setting:`STATICFILES_FINDERS`.
* The default for :setting:`STATICFILES_STORAGE` was renamed from
``staticfiles.storage.StaticFileStorage`` to
``staticfiles.storage.StaticFilesStorage``
* The default for :setting:`STATICFILES_STORAGE` was renamed from
``staticfiles.storage.StaticFileStorage`` to
``staticfiles.storage.StaticFilesStorage``
* If using :ref:`runserver<staticfiles-runserver>` for local development
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
anything to your URLconf for serving static files in development.
* If using :ref:`runserver<staticfiles-runserver>` for local development
(and the :setting:`DEBUG` setting is ``True``), you no longer need to add
anything to your URLconf for serving static files in development.
Learn more
==========