Removed use of non-standard indentation rules in docs, and the custom transform that supported them.
Doc writers should be aware that we are now back to normal ReST rules regarding blockquotes. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16955 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
af244e47cc
commit
c61987d75a
|
@ -62,7 +62,6 @@ def setup(app):
|
||||||
app.add_config_value('django_next_version', '0.0', True)
|
app.add_config_value('django_next_version', '0.0', True)
|
||||||
app.add_directive('versionadded', VersionDirective)
|
app.add_directive('versionadded', VersionDirective)
|
||||||
app.add_directive('versionchanged', VersionDirective)
|
app.add_directive('versionchanged', VersionDirective)
|
||||||
app.add_transform(SuppressBlockquotes)
|
|
||||||
app.add_builder(DjangoStandaloneHTMLBuilder)
|
app.add_builder(DjangoStandaloneHTMLBuilder)
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,27 +98,6 @@ class VersionDirective(Directive):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class SuppressBlockquotes(transforms.Transform):
|
|
||||||
"""
|
|
||||||
Remove the default blockquotes that encase indented list, tables, etc.
|
|
||||||
"""
|
|
||||||
default_priority = 300
|
|
||||||
|
|
||||||
suppress_blockquote_child_nodes = (
|
|
||||||
nodes.bullet_list,
|
|
||||||
nodes.enumerated_list,
|
|
||||||
nodes.definition_list,
|
|
||||||
nodes.literal_block,
|
|
||||||
nodes.doctest_block,
|
|
||||||
nodes.line_block,
|
|
||||||
nodes.table
|
|
||||||
)
|
|
||||||
|
|
||||||
def apply(self):
|
|
||||||
for node in self.document.traverse(nodes.block_quote):
|
|
||||||
if len(node.children) == 1 and isinstance(node.children[0], self.suppress_blockquote_child_nodes):
|
|
||||||
node.replace_self(node.children[0])
|
|
||||||
|
|
||||||
class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
|
class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
|
||||||
"""
|
"""
|
||||||
Django-specific reST to HTML tweaks.
|
Django-specific reST to HTML tweaks.
|
||||||
|
|
|
@ -16,31 +16,31 @@ Overview
|
||||||
|
|
||||||
There are seven steps in activating the Django admin site:
|
There are seven steps in activating the Django admin site:
|
||||||
|
|
||||||
1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
|
1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
|
||||||
setting.
|
setting.
|
||||||
|
|
||||||
2. The admin has four dependencies - :mod:`django.contrib.auth`,
|
2. The admin has four dependencies - :mod:`django.contrib.auth`,
|
||||||
:mod:`django.contrib.contenttypes`,
|
:mod:`django.contrib.contenttypes`,
|
||||||
:mod:`django.contrib.messages` and
|
:mod:`django.contrib.messages` and
|
||||||
:mod:`django.contrib.sessions`. If these applications are not
|
:mod:`django.contrib.sessions`. If these applications are not
|
||||||
in your :setting:`INSTALLED_APPS` list, add them.
|
in your :setting:`INSTALLED_APPS` list, add them.
|
||||||
|
|
||||||
3. Add ``django.contrib.messages.context_processors.messages`` to
|
3. Add ``django.contrib.messages.context_processors.messages`` to
|
||||||
:setting:`TEMPLATE_CONTEXT_PROCESSORS` and
|
:setting:`TEMPLATE_CONTEXT_PROCESSORS` and
|
||||||
:class:`~django.contrib.messages.middleware.MessageMiddleware` to
|
:class:`~django.contrib.messages.middleware.MessageMiddleware` to
|
||||||
:setting:`MIDDLEWARE_CLASSES`.
|
:setting:`MIDDLEWARE_CLASSES`.
|
||||||
|
|
||||||
4. Determine which of your application's models should be editable in the
|
4. Determine which of your application's models should be editable in the
|
||||||
admin interface.
|
admin interface.
|
||||||
|
|
||||||
5. For each of those models, optionally create a ``ModelAdmin`` class that
|
5. For each of those models, optionally create a ``ModelAdmin`` class that
|
||||||
encapsulates the customized admin functionality and options for that
|
encapsulates the customized admin functionality and options for that
|
||||||
particular model.
|
particular model.
|
||||||
|
|
||||||
6. Instantiate an ``AdminSite`` and tell it about each of your models and
|
6. Instantiate an ``AdminSite`` and tell it about each of your models and
|
||||||
``ModelAdmin`` classes.
|
``ModelAdmin`` classes.
|
||||||
|
|
||||||
7. Hook the ``AdminSite`` instance into your URLconf.
|
7. Hook the ``AdminSite`` instance into your URLconf.
|
||||||
|
|
||||||
Other topics
|
Other topics
|
||||||
------------
|
------------
|
||||||
|
@ -239,54 +239,54 @@ subclass::
|
||||||
|
|
||||||
The ``field_options`` dictionary can have the following keys:
|
The ``field_options`` dictionary can have the following keys:
|
||||||
|
|
||||||
* ``fields``
|
* ``fields``
|
||||||
A tuple of field names to display in this fieldset. This key is
|
A tuple of field names to display in this fieldset. This key is
|
||||||
required.
|
required.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
{
|
{
|
||||||
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
|
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
|
||||||
}
|
}
|
||||||
|
|
||||||
Just like with the :attr:`~ModelAdmin.fields` option, to display
|
Just like with the :attr:`~ModelAdmin.fields` option, to display
|
||||||
multiple fields on the same line, wrap those fields in their own
|
multiple fields on the same line, wrap those fields in their own
|
||||||
tuple. In this example, the ``first_name`` and ``last_name`` fields
|
tuple. In this example, the ``first_name`` and ``last_name`` fields
|
||||||
will display on the same line::
|
will display on the same line::
|
||||||
|
|
||||||
{
|
{
|
||||||
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
|
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
|
||||||
}
|
}
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
``fields`` can contain values defined in
|
``fields`` can contain values defined in
|
||||||
:attr:`~ModelAdmin.readonly_fields` to be displayed as read-only.
|
:attr:`~ModelAdmin.readonly_fields` to be displayed as read-only.
|
||||||
|
|
||||||
* ``classes``
|
* ``classes``
|
||||||
A list containing extra CSS classes to apply to the fieldset.
|
A list containing extra CSS classes to apply to the fieldset.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
{
|
{
|
||||||
'classes': ['wide', 'extrapretty'],
|
'classes': ['wide', 'extrapretty'],
|
||||||
}
|
}
|
||||||
|
|
||||||
Two useful classes defined by the default admin site stylesheet are
|
Two useful classes defined by the default admin site stylesheet are
|
||||||
``collapse`` and ``wide``. Fieldsets with the ``collapse`` style
|
``collapse`` and ``wide``. Fieldsets with the ``collapse`` style
|
||||||
will be initially collapsed in the admin and replaced with a small
|
will be initially collapsed in the admin and replaced with a small
|
||||||
"click to expand" link. Fieldsets with the ``wide`` style will be
|
"click to expand" link. Fieldsets with the ``wide`` style will be
|
||||||
given extra horizontal space.
|
given extra horizontal space.
|
||||||
|
|
||||||
* ``description``
|
* ``description``
|
||||||
A string of optional extra text to be displayed at the top of each
|
A string of optional extra text to be displayed at the top of each
|
||||||
fieldset, under the heading of the fieldset.
|
fieldset, under the heading of the fieldset.
|
||||||
|
|
||||||
Note that this value is *not* HTML-escaped when it's displayed in
|
Note that this value is *not* HTML-escaped when it's displayed in
|
||||||
the admin interface. This lets you include HTML if you so desire.
|
the admin interface. This lets you include HTML if you so desire.
|
||||||
Alternatively you can use plain text and
|
Alternatively you can use plain text and
|
||||||
``django.utils.html.escape()`` to escape any HTML special
|
``django.utils.html.escape()`` to escape any HTML special
|
||||||
characters.
|
characters.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.filter_horizontal
|
.. attribute:: ModelAdmin.filter_horizontal
|
||||||
|
|
||||||
|
@ -400,129 +400,129 @@ subclass::
|
||||||
|
|
||||||
You have four possible values that can be used in ``list_display``:
|
You have four possible values that can be used in ``list_display``:
|
||||||
|
|
||||||
* A field of the model. For example::
|
* A field of the model. For example::
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
list_display = ('first_name', 'last_name')
|
list_display = ('first_name', 'last_name')
|
||||||
|
|
||||||
* A callable that accepts one parameter for the model instance. For
|
* A callable that accepts one parameter for the model instance. For
|
||||||
example::
|
example::
|
||||||
|
|
||||||
def upper_case_name(obj):
|
def upper_case_name(obj):
|
||||||
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
|
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
|
||||||
|
upper_case_name.short_description = 'Name'
|
||||||
|
|
||||||
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
|
list_display = (upper_case_name,)
|
||||||
|
|
||||||
|
* A string representing an attribute on the ``ModelAdmin``. This
|
||||||
|
behaves same as the callable. For example::
|
||||||
|
|
||||||
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('upper_case_name',)
|
||||||
|
|
||||||
|
def upper_case_name(self, obj):
|
||||||
|
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
|
||||||
upper_case_name.short_description = 'Name'
|
upper_case_name.short_description = 'Name'
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
* A string representing an attribute on the model. This behaves almost
|
||||||
list_display = (upper_case_name,)
|
the same as the callable, but ``self`` in this context is the model
|
||||||
|
instance. Here's a full model example::
|
||||||
|
|
||||||
* A string representing an attribute on the ``ModelAdmin``. This
|
class Person(models.Model):
|
||||||
behaves same as the callable. For example::
|
name = models.CharField(max_length=50)
|
||||||
|
birthday = models.DateField()
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
def decade_born_in(self):
|
||||||
list_display = ('upper_case_name',)
|
return self.birthday.strftime('%Y')[:3] + "0's"
|
||||||
|
decade_born_in.short_description = 'Birth decade'
|
||||||
|
|
||||||
def upper_case_name(self, obj):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
|
list_display = ('name', 'decade_born_in')
|
||||||
upper_case_name.short_description = 'Name'
|
|
||||||
|
|
||||||
* A string representing an attribute on the model. This behaves almost
|
|
||||||
the same as the callable, but ``self`` in this context is the model
|
|
||||||
instance. Here's a full model example::
|
|
||||||
|
|
||||||
class Person(models.Model):
|
|
||||||
name = models.CharField(max_length=50)
|
|
||||||
birthday = models.DateField()
|
|
||||||
|
|
||||||
def decade_born_in(self):
|
|
||||||
return self.birthday.strftime('%Y')[:3] + "0's"
|
|
||||||
decade_born_in.short_description = 'Birth decade'
|
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
|
||||||
list_display = ('name', 'decade_born_in')
|
|
||||||
|
|
||||||
A few special cases to note about ``list_display``:
|
A few special cases to note about ``list_display``:
|
||||||
|
|
||||||
* If the field is a ``ForeignKey``, Django will display the
|
* If the field is a ``ForeignKey``, Django will display the
|
||||||
``__unicode__()`` of the related object.
|
``__unicode__()`` of the related object.
|
||||||
|
|
||||||
* ``ManyToManyField`` fields aren't supported, because that would
|
* ``ManyToManyField`` fields aren't supported, because that would
|
||||||
entail executing a separate SQL statement for each row in the table.
|
entail executing a separate SQL statement for each row in the table.
|
||||||
If you want to do this nonetheless, give your model a custom method,
|
If you want to do this nonetheless, give your model a custom method,
|
||||||
and add that method's name to ``list_display``. (See below for more
|
and add that method's name to ``list_display``. (See below for more
|
||||||
on custom methods in ``list_display``.)
|
on custom methods in ``list_display``.)
|
||||||
|
|
||||||
* If the field is a ``BooleanField`` or ``NullBooleanField``, Django
|
* If the field is a ``BooleanField`` or ``NullBooleanField``, Django
|
||||||
will display a pretty "on" or "off" icon instead of ``True`` or
|
will display a pretty "on" or "off" icon instead of ``True`` or
|
||||||
``False``.
|
``False``.
|
||||||
|
|
||||||
* If the string given is a method of the model, ``ModelAdmin`` or a
|
* If the string given is a method of the model, ``ModelAdmin`` or a
|
||||||
callable, Django will HTML-escape the output by default. If you'd
|
callable, Django will HTML-escape the output by default. If you'd
|
||||||
rather not escape the output of the method, give the method an
|
rather not escape the output of the method, give the method an
|
||||||
``allow_tags`` attribute whose value is ``True``.
|
``allow_tags`` attribute whose value is ``True``.
|
||||||
|
|
||||||
Here's a full example model::
|
Here's a full example model::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(max_length=50)
|
first_name = models.CharField(max_length=50)
|
||||||
last_name = models.CharField(max_length=50)
|
last_name = models.CharField(max_length=50)
|
||||||
color_code = models.CharField(max_length=6)
|
color_code = models.CharField(max_length=6)
|
||||||
|
|
||||||
def colored_name(self):
|
def colored_name(self):
|
||||||
return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
|
return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
|
||||||
colored_name.allow_tags = True
|
colored_name.allow_tags = True
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
list_display = ('first_name', 'last_name', 'colored_name')
|
list_display = ('first_name', 'last_name', 'colored_name')
|
||||||
|
|
||||||
* If the string given is a method of the model, ``ModelAdmin`` or a
|
* If the string given is a method of the model, ``ModelAdmin`` or a
|
||||||
callable that returns True or False Django will display a pretty
|
callable that returns True or False Django will display a pretty
|
||||||
"on" or "off" icon if you give the method a ``boolean`` attribute
|
"on" or "off" icon if you give the method a ``boolean`` attribute
|
||||||
whose value is ``True``.
|
whose value is ``True``.
|
||||||
|
|
||||||
Here's a full example model::
|
Here's a full example model::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(max_length=50)
|
first_name = models.CharField(max_length=50)
|
||||||
birthday = models.DateField()
|
birthday = models.DateField()
|
||||||
|
|
||||||
def born_in_fifties(self):
|
def born_in_fifties(self):
|
||||||
return self.birthday.strftime('%Y')[:3] == '195'
|
return self.birthday.strftime('%Y')[:3] == '195'
|
||||||
born_in_fifties.boolean = True
|
born_in_fifties.boolean = True
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'born_in_fifties')
|
list_display = ('name', 'born_in_fifties')
|
||||||
|
|
||||||
|
|
||||||
* The ``__str__()`` and ``__unicode__()`` methods are just as valid in
|
* The ``__str__()`` and ``__unicode__()`` methods are just as valid in
|
||||||
``list_display`` as any other model method, so it's perfectly OK to
|
``list_display`` as any other model method, so it's perfectly OK to
|
||||||
do this::
|
do this::
|
||||||
|
|
||||||
list_display = ('__unicode__', 'some_other_field')
|
list_display = ('__unicode__', 'some_other_field')
|
||||||
|
|
||||||
* Usually, elements of ``list_display`` that aren't actual database
|
* Usually, elements of ``list_display`` that aren't actual database
|
||||||
fields can't be used in sorting (because Django does all the sorting
|
fields can't be used in sorting (because Django does all the sorting
|
||||||
at the database level).
|
at the database level).
|
||||||
|
|
||||||
However, if an element of ``list_display`` represents a certain
|
However, if an element of ``list_display`` represents a certain
|
||||||
database field, you can indicate this fact by setting the
|
database field, you can indicate this fact by setting the
|
||||||
``admin_order_field`` attribute of the item.
|
``admin_order_field`` attribute of the item.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
first_name = models.CharField(max_length=50)
|
first_name = models.CharField(max_length=50)
|
||||||
color_code = models.CharField(max_length=6)
|
color_code = models.CharField(max_length=6)
|
||||||
|
|
||||||
def colored_first_name(self):
|
def colored_first_name(self):
|
||||||
return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
|
return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
|
||||||
colored_first_name.allow_tags = True
|
colored_first_name.allow_tags = True
|
||||||
colored_first_name.admin_order_field = 'first_name'
|
colored_first_name.admin_order_field = 'first_name'
|
||||||
|
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
list_display = ('first_name', 'colored_first_name')
|
list_display = ('first_name', 'colored_first_name')
|
||||||
|
|
||||||
The above will tell Django to order by the ``first_name`` field when
|
The above will tell Django to order by the ``first_name`` field when
|
||||||
trying to sort by ``colored_first_name`` in the admin.
|
trying to sort by ``colored_first_name`` in the admin.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.list_display_links
|
.. attribute:: ModelAdmin.list_display_links
|
||||||
|
|
||||||
|
@ -561,12 +561,12 @@ subclass::
|
||||||
``list_editable`` interacts with a couple of other options in
|
``list_editable`` interacts with a couple of other options in
|
||||||
particular ways; you should note the following rules:
|
particular ways; you should note the following rules:
|
||||||
|
|
||||||
* Any field in ``list_editable`` must also be in ``list_display``.
|
* Any field in ``list_editable`` must also be in ``list_display``.
|
||||||
You can't edit a field that's not displayed!
|
You can't edit a field that's not displayed!
|
||||||
|
|
||||||
* The same field can't be listed in both ``list_editable`` and
|
* The same field can't be listed in both ``list_editable`` and
|
||||||
``list_display_links`` -- a field can't be both a form and
|
``list_display_links`` -- a field can't be both a form and
|
||||||
a link.
|
a link.
|
||||||
|
|
||||||
You'll get a validation error if either of these rules are broken.
|
You'll get a validation error if either of these rules are broken.
|
||||||
|
|
||||||
|
@ -582,119 +582,119 @@ subclass::
|
||||||
``list_filter`` should be a list of elements, where each element should be
|
``list_filter`` should be a list of elements, where each element should be
|
||||||
of one of the following types:
|
of one of the following types:
|
||||||
|
|
||||||
* a field name, where the specified field should be either a
|
* a field name, where the specified field should be either a
|
||||||
``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
||||||
``IntegerField``, ``ForeignKey`` or ``ManyToManyField``, for example::
|
``IntegerField``, ``ForeignKey`` or ``ManyToManyField``, for example::
|
||||||
|
|
||||||
class PersonAdmin(ModelAdmin):
|
class PersonAdmin(ModelAdmin):
|
||||||
list_filter = ('is_staff', 'company')
|
list_filter = ('is_staff', 'company')
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
Field names in ``list_filter`` can also span relations
|
Field names in ``list_filter`` can also span relations
|
||||||
using the ``__`` lookup, for example::
|
using the ``__`` lookup, for example::
|
||||||
|
|
||||||
class PersonAdmin(UserAdmin):
|
class PersonAdmin(UserAdmin):
|
||||||
list_filter = ('company__name',)
|
list_filter = ('company__name',)
|
||||||
|
|
||||||
* a class inheriting from :mod:`django.contrib.admin.SimpleListFilter`,
|
* a class inheriting from :mod:`django.contrib.admin.SimpleListFilter`,
|
||||||
which you need to provide the ``title`` and ``parameter_name``
|
which you need to provide the ``title`` and ``parameter_name``
|
||||||
attributes to and override the ``lookups`` and ``queryset`` methods,
|
attributes to and override the ``lookups`` and ``queryset`` methods,
|
||||||
e.g.::
|
e.g.::
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.contrib.admin import SimpleListFilter
|
from django.contrib.admin import SimpleListFilter
|
||||||
|
|
||||||
class DecadeBornListFilter(SimpleListFilter):
|
class DecadeBornListFilter(SimpleListFilter):
|
||||||
# Human-readable title which will be displayed in the
|
# Human-readable title which will be displayed in the
|
||||||
# right admin sidebar just above the filter options.
|
# right admin sidebar just above the filter options.
|
||||||
title = _('decade born')
|
title = _('decade born')
|
||||||
|
|
||||||
# Parameter for the filter that will be used in the URL query.
|
# Parameter for the filter that will be used in the URL query.
|
||||||
parameter_name = 'decade'
|
parameter_name = 'decade'
|
||||||
|
|
||||||
def lookups(self, request, model_admin):
|
def lookups(self, request, model_admin):
|
||||||
"""
|
"""
|
||||||
Returns a list of tuples. The first element in each
|
Returns a list of tuples. The first element in each
|
||||||
tuple is the coded value for the option that will
|
tuple is the coded value for the option that will
|
||||||
appear in the URL query. The second element is the
|
appear in the URL query. The second element is the
|
||||||
human-readable name for the option that will appear
|
human-readable name for the option that will appear
|
||||||
in the right sidebar.
|
in the right sidebar.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
('80s', _('in the eighties')),
|
('80s', _('in the eighties')),
|
||||||
('90s', _('in the nineties')),
|
('90s', _('in the nineties')),
|
||||||
)
|
)
|
||||||
|
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
"""
|
"""
|
||||||
Returns the filtered queryset based on the value
|
Returns the filtered queryset based on the value
|
||||||
provided in the query string and retrievable via
|
provided in the query string and retrievable via
|
||||||
`self.value()`.
|
`self.value()`.
|
||||||
"""
|
"""
|
||||||
# Compare the requested value (either '80s' or 'other')
|
# Compare the requested value (either '80s' or 'other')
|
||||||
# to decide how to filter the queryset.
|
# to decide how to filter the queryset.
|
||||||
if self.value() == '80s':
|
if self.value() == '80s':
|
||||||
return queryset.filter(birthday__year__gte=1980,
|
return queryset.filter(birthday__year__gte=1980,
|
||||||
birthday__year__lte=1989)
|
birthday__year__lte=1989)
|
||||||
if self.value() == '90s':
|
if self.value() == '90s':
|
||||||
return queryset.filter(birthday__year__gte=1990,
|
return queryset.filter(birthday__year__gte=1990,
|
||||||
birthday__year__lte=1999)
|
birthday__year__lte=1999)
|
||||||
|
|
||||||
class PersonAdmin(ModelAdmin):
|
class PersonAdmin(ModelAdmin):
|
||||||
list_filter = (DecadeBornListFilter,)
|
list_filter = (DecadeBornListFilter,)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
As a convenience, the ``HttpRequest`` object is passed to the
|
As a convenience, the ``HttpRequest`` object is passed to the
|
||||||
``lookups`` and ``queryset`` methods, for example::
|
``lookups`` and ``queryset`` methods, for example::
|
||||||
|
|
||||||
class AuthDecadeBornListFilter(DecadeBornListFilter):
|
class AuthDecadeBornListFilter(DecadeBornListFilter):
|
||||||
|
|
||||||
def lookups(self, request, model_admin):
|
def lookups(self, request, model_admin):
|
||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
return super(AuthDecadeBornListFilter,
|
return super(AuthDecadeBornListFilter,
|
||||||
self).lookups(request, model_admin)
|
self).lookups(request, model_admin)
|
||||||
|
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
return super(AuthDecadeBornListFilter,
|
return super(AuthDecadeBornListFilter,
|
||||||
self).queryset(request, queryset)
|
self).queryset(request, queryset)
|
||||||
|
|
||||||
Also as a convenience, the ``ModelAdmin`` object is passed to
|
Also as a convenience, the ``ModelAdmin`` object is passed to
|
||||||
the ``lookups`` method, for example if you want to base the
|
the ``lookups`` method, for example if you want to base the
|
||||||
lookups on the available data::
|
lookups on the available data::
|
||||||
|
|
||||||
class AdvancedDecadeBornListFilter(DecadeBornListFilter):
|
class AdvancedDecadeBornListFilter(DecadeBornListFilter):
|
||||||
|
|
||||||
def lookups(self, request, model_admin):
|
def lookups(self, request, model_admin):
|
||||||
"""
|
"""
|
||||||
Only show the lookups if there actually is
|
Only show the lookups if there actually is
|
||||||
anyone born in the corresponding decades.
|
anyone born in the corresponding decades.
|
||||||
"""
|
"""
|
||||||
qs = model_admin.queryset(request)
|
qs = model_admin.queryset(request)
|
||||||
if qs.filter(birthday__year__gte=1980,
|
if qs.filter(birthday__year__gte=1980,
|
||||||
birthday__year__lte=1989).exists():
|
birthday__year__lte=1989).exists():
|
||||||
yield ('80s', _('in the eighties'))
|
yield ('80s', _('in the eighties'))
|
||||||
if qs.filter(birthday__year__gte=1990,
|
if qs.filter(birthday__year__gte=1990,
|
||||||
birthday__year__lte=1999).exists():
|
birthday__year__lte=1999).exists():
|
||||||
yield ('90s', _('in the nineties'))
|
yield ('90s', _('in the nineties'))
|
||||||
|
|
||||||
* a tuple, where the first element is a field name and the second
|
* a tuple, where the first element is a field name and the second
|
||||||
element is a class inheriting from
|
element is a class inheriting from
|
||||||
:mod:`django.contrib.admin.FieldListFilter`, for example::
|
:mod:`django.contrib.admin.FieldListFilter`, for example::
|
||||||
|
|
||||||
from django.contrib.admin import BooleanFieldListFilter
|
from django.contrib.admin import BooleanFieldListFilter
|
||||||
|
|
||||||
class PersonAdmin(ModelAdmin):
|
class PersonAdmin(ModelAdmin):
|
||||||
list_filter = (
|
list_filter = (
|
||||||
('is_staff', BooleanFieldListFilter),
|
('is_staff', BooleanFieldListFilter),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The ``FieldListFilter`` API is currently considered internal
|
The ``FieldListFilter`` API is currently considered internal
|
||||||
and prone to refactoring.
|
and prone to refactoring.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.list_max_show_all
|
.. attribute:: ModelAdmin.list_max_show_all
|
||||||
|
|
||||||
|
@ -1076,11 +1076,11 @@ templates used by the :class:`ModelAdmin` views:
|
||||||
However, the ``self.my_view`` function registered above suffers from two
|
However, the ``self.my_view`` function registered above suffers from two
|
||||||
problems:
|
problems:
|
||||||
|
|
||||||
* It will *not* perform any permission checks, so it will be accessible
|
* It will *not* perform any permission checks, so it will be accessible
|
||||||
to the general public.
|
to the general public.
|
||||||
* It will *not* provide any header details to prevent caching. This means
|
* It will *not* provide any header details to prevent caching. This means
|
||||||
if the page retrieves data from the database, and caching middleware is
|
if the page retrieves data from the database, and caching middleware is
|
||||||
active, the page could show outdated information.
|
active, the page could show outdated information.
|
||||||
|
|
||||||
Since this is usually not what you want, Django provides a convenience
|
Since this is usually not what you want, Django provides a convenience
|
||||||
wrapper to check permissions and mark the view as non-cacheable. This
|
wrapper to check permissions and mark the view as non-cacheable. This
|
||||||
|
@ -1356,8 +1356,8 @@ information.
|
||||||
|
|
||||||
Django provides two subclasses of ``InlineModelAdmin`` and they are:
|
Django provides two subclasses of ``InlineModelAdmin`` and they are:
|
||||||
|
|
||||||
* :class:`~django.contrib.admin.TabularInline`
|
* :class:`~django.contrib.admin.TabularInline`
|
||||||
* :class:`~django.contrib.admin.StackedInline`
|
* :class:`~django.contrib.admin.StackedInline`
|
||||||
|
|
||||||
The difference between these two is merely the template used to render
|
The difference between these two is merely the template used to render
|
||||||
them.
|
them.
|
||||||
|
@ -1735,11 +1735,11 @@ Templates which may be overridden per app or model
|
||||||
Not every template in ``contrib/admin/templates/admin`` may be overridden per
|
Not every template in ``contrib/admin/templates/admin`` may be overridden per
|
||||||
app or per model. The following can:
|
app or per model. The following can:
|
||||||
|
|
||||||
* ``app_index.html``
|
* ``app_index.html``
|
||||||
* ``change_form.html``
|
* ``change_form.html``
|
||||||
* ``change_list.html``
|
* ``change_list.html``
|
||||||
* ``delete_confirmation.html``
|
* ``delete_confirmation.html``
|
||||||
* ``object_history.html``
|
* ``object_history.html``
|
||||||
|
|
||||||
For those templates that cannot be overridden in this way, you may still
|
For those templates that cannot be overridden in this way, you may still
|
||||||
override them for your entire project. Just place the new version in your
|
override them for your entire project. Just place the new version in your
|
||||||
|
@ -1920,28 +1920,28 @@ accessible using Django's :ref:`URL reversing system <naming-url-patterns>`.
|
||||||
|
|
||||||
The :class:`AdminSite` provides the following named URL patterns:
|
The :class:`AdminSite` provides the following named URL patterns:
|
||||||
|
|
||||||
====================== ======================== =============
|
====================== ======================== =============
|
||||||
Page URL name Parameters
|
Page URL name Parameters
|
||||||
====================== ======================== =============
|
====================== ======================== =============
|
||||||
Index ``index``
|
Index ``index``
|
||||||
Logout ``logout``
|
Logout ``logout``
|
||||||
Password change ``password_change``
|
Password change ``password_change``
|
||||||
Password change done ``password_change_done``
|
Password change done ``password_change_done``
|
||||||
i18n javascript ``jsi18n``
|
i18n javascript ``jsi18n``
|
||||||
Application index page ``app_list`` ``app_label``
|
Application index page ``app_list`` ``app_label``
|
||||||
====================== ======================== =============
|
====================== ======================== =============
|
||||||
|
|
||||||
Each :class:`ModelAdmin` instance provides an additional set of named URLs:
|
Each :class:`ModelAdmin` instance provides an additional set of named URLs:
|
||||||
|
|
||||||
====================== =============================================== =============
|
====================== =============================================== =============
|
||||||
Page URL name Parameters
|
Page URL name Parameters
|
||||||
====================== =============================================== =============
|
====================== =============================================== =============
|
||||||
Changelist ``{{ app_label }}_{{ model_name }}_changelist``
|
Changelist ``{{ app_label }}_{{ model_name }}_changelist``
|
||||||
Add ``{{ app_label }}_{{ model_name }}_add``
|
Add ``{{ app_label }}_{{ model_name }}_add``
|
||||||
History ``{{ app_label }}_{{ model_name }}_history`` ``object_id``
|
History ``{{ app_label }}_{{ model_name }}_history`` ``object_id``
|
||||||
Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id``
|
Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id``
|
||||||
Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id``
|
Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id``
|
||||||
====================== =============================================== =============
|
====================== =============================================== =============
|
||||||
|
|
||||||
These named URLs are registered with the application namespace ``admin``, and
|
These named URLs are registered with the application namespace ``admin``, and
|
||||||
with an instance namespace corresponding to the name of the Site instance.
|
with an instance namespace corresponding to the name of the Site instance.
|
||||||
|
|
|
@ -125,12 +125,12 @@ moderate comments"``) can approve and delete comments. This can also be
|
||||||
done through the ``admin`` as you'll see later. You might also want to
|
done through the ``admin`` as you'll see later. You might also want to
|
||||||
customize the following templates:
|
customize the following templates:
|
||||||
|
|
||||||
* ``flag.html``
|
* ``flag.html``
|
||||||
* ``flagged.html``
|
* ``flagged.html``
|
||||||
* ``approve.html``
|
* ``approve.html``
|
||||||
* ``approved.html``
|
* ``approved.html``
|
||||||
* ``delete.html``
|
* ``delete.html``
|
||||||
* ``deleted.html``
|
* ``deleted.html``
|
||||||
|
|
||||||
found under the directory structure we saw for ``form.html``.
|
found under the directory structure we saw for ``form.html``.
|
||||||
|
|
||||||
|
@ -185,9 +185,9 @@ in-built with :doc:`generic comment moderation
|
||||||
</ref/contrib/comments/moderation>`. The comment moderation has the following
|
</ref/contrib/comments/moderation>`. The comment moderation has the following
|
||||||
features (all of which or only certain can be enabled):
|
features (all of which or only certain can be enabled):
|
||||||
|
|
||||||
* Enable comments for a particular model instance.
|
* Enable comments for a particular model instance.
|
||||||
* Close comments after a particular (user-defined) number of days.
|
* Close comments after a particular (user-defined) number of days.
|
||||||
* Email new comments to the site-staff.
|
* Email new comments to the site-staff.
|
||||||
|
|
||||||
To enable comment moderation, we subclass the :class:`CommentModerator` and
|
To enable comment moderation, we subclass the :class:`CommentModerator` and
|
||||||
register it with the moderation features we want. Let us suppose we want to
|
register it with the moderation features we want. Let us suppose we want to
|
||||||
|
|
|
@ -36,49 +36,49 @@ Supported countries
|
||||||
|
|
||||||
Countries currently supported by :mod:`~django.contrib.localflavor` are:
|
Countries currently supported by :mod:`~django.contrib.localflavor` are:
|
||||||
|
|
||||||
* Argentina_
|
* Argentina_
|
||||||
* Australia_
|
* Australia_
|
||||||
* Austria_
|
* Austria_
|
||||||
* Belgium_
|
* Belgium_
|
||||||
* Brazil_
|
* Brazil_
|
||||||
* Canada_
|
* Canada_
|
||||||
* Chile_
|
* Chile_
|
||||||
* China_
|
* China_
|
||||||
* Colombia_
|
* Colombia_
|
||||||
* Croatia_
|
* Croatia_
|
||||||
* Czech_
|
* Czech_
|
||||||
* Ecuador_
|
* Ecuador_
|
||||||
* Finland_
|
* Finland_
|
||||||
* France_
|
* France_
|
||||||
* Germany_
|
* Germany_
|
||||||
* Iceland_
|
* Iceland_
|
||||||
* India_
|
* India_
|
||||||
* Indonesia_
|
* Indonesia_
|
||||||
* Ireland_
|
* Ireland_
|
||||||
* Israel_
|
* Israel_
|
||||||
* Italy_
|
* Italy_
|
||||||
* Japan_
|
* Japan_
|
||||||
* Kuwait_
|
* Kuwait_
|
||||||
* Macedonia_
|
* Macedonia_
|
||||||
* Mexico_
|
* Mexico_
|
||||||
* `The Netherlands`_
|
* `The Netherlands`_
|
||||||
* Norway_
|
* Norway_
|
||||||
* Peru_
|
* Peru_
|
||||||
* Poland_
|
* Poland_
|
||||||
* Portugal_
|
* Portugal_
|
||||||
* Paraguay_
|
* Paraguay_
|
||||||
* Romania_
|
* Romania_
|
||||||
* Russia_
|
* Russia_
|
||||||
* Slovakia_
|
* Slovakia_
|
||||||
* Slovenia_
|
* Slovenia_
|
||||||
* `South Africa`_
|
* `South Africa`_
|
||||||
* Spain_
|
* Spain_
|
||||||
* Sweden_
|
* Sweden_
|
||||||
* Switzerland_
|
* Switzerland_
|
||||||
* Turkey_
|
* Turkey_
|
||||||
* `United Kingdom`_
|
* `United Kingdom`_
|
||||||
* `United States of America`_
|
* `United States of America`_
|
||||||
* Uruguay_
|
* Uruguay_
|
||||||
|
|
||||||
The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage,
|
The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage,
|
||||||
containing useful code that is not specific to one particular country or culture.
|
containing useful code that is not specific to one particular country or culture.
|
||||||
|
@ -1286,13 +1286,13 @@ United States of America (``us``)
|
||||||
A form field that validates input as a U.S. Social Security Number (SSN).
|
A form field that validates input as a U.S. Social Security Number (SSN).
|
||||||
A valid SSN must obey the following rules:
|
A valid SSN must obey the following rules:
|
||||||
|
|
||||||
* Format of XXX-XX-XXXX
|
* Format of XXX-XX-XXXX
|
||||||
* No group of digits consisting entirely of zeroes
|
* No group of digits consisting entirely of zeroes
|
||||||
* Leading group of digits cannot be 666
|
* Leading group of digits cannot be 666
|
||||||
* Number not in promotional block 987-65-4320 through 987-65-4329
|
* Number not in promotional block 987-65-4320 through 987-65-4329
|
||||||
* Number not one known to be invalid due to widespread promotional
|
* Number not one known to be invalid due to widespread promotional
|
||||||
use or distribution (e.g., the Woolworth's number or the 1962
|
use or distribution (e.g., the Woolworth's number or the 1962
|
||||||
promotional number)
|
promotional number)
|
||||||
|
|
||||||
.. class:: us.forms.USStateField
|
.. class:: us.forms.USStateField
|
||||||
|
|
||||||
|
|
|
@ -24,57 +24,57 @@ actually occurs until you do something to evaluate the queryset.
|
||||||
|
|
||||||
You can evaluate a ``QuerySet`` in the following ways:
|
You can evaluate a ``QuerySet`` in the following ways:
|
||||||
|
|
||||||
* **Iteration.** A ``QuerySet`` is iterable, and it executes its database
|
* **Iteration.** A ``QuerySet`` is iterable, and it executes its database
|
||||||
query the first time you iterate over it. For example, this will print
|
query the first time you iterate over it. For example, this will print
|
||||||
the headline of all entries in the database::
|
the headline of all entries in the database::
|
||||||
|
|
||||||
for e in Entry.objects.all():
|
for e in Entry.objects.all():
|
||||||
print e.headline
|
print e.headline
|
||||||
|
|
||||||
* **Slicing.** As explained in :ref:`limiting-querysets`, a ``QuerySet`` can
|
* **Slicing.** As explained in :ref:`limiting-querysets`, a ``QuerySet`` can
|
||||||
be sliced, using Python's array-slicing syntax. Usually slicing a
|
be sliced, using Python's array-slicing syntax. Usually slicing a
|
||||||
``QuerySet`` returns another (unevaluated) ``QuerySet``, but Django will
|
``QuerySet`` returns another (unevaluated) ``QuerySet``, but Django will
|
||||||
execute the database query if you use the "step" parameter of slice
|
execute the database query if you use the "step" parameter of slice
|
||||||
syntax.
|
syntax.
|
||||||
|
|
||||||
* **Pickling/Caching.** See the following section for details of what
|
* **Pickling/Caching.** See the following section for details of what
|
||||||
is involved when `pickling QuerySets`_. The important thing for the
|
is involved when `pickling QuerySets`_. The important thing for the
|
||||||
purposes of this section is that the results are read from the database.
|
purposes of this section is that the results are read from the database.
|
||||||
|
|
||||||
* **repr().** A ``QuerySet`` is evaluated when you call ``repr()`` on it.
|
* **repr().** A ``QuerySet`` is evaluated when you call ``repr()`` on it.
|
||||||
This is for convenience in the Python interactive interpreter, so you can
|
This is for convenience in the Python interactive interpreter, so you can
|
||||||
immediately see your results when using the API interactively.
|
immediately see your results when using the API interactively.
|
||||||
|
|
||||||
* **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it.
|
* **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it.
|
||||||
This, as you might expect, returns the length of the result list.
|
This, as you might expect, returns the length of the result list.
|
||||||
|
|
||||||
Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is
|
Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is
|
||||||
determine the number of records in the set. It's much more efficient to
|
determine the number of records in the set. It's much more efficient to
|
||||||
handle a count at the database level, using SQL's ``SELECT COUNT(*)``,
|
handle a count at the database level, using SQL's ``SELECT COUNT(*)``,
|
||||||
and Django provides a ``count()`` method for precisely this reason. See
|
and Django provides a ``count()`` method for precisely this reason. See
|
||||||
``count()`` below.
|
``count()`` below.
|
||||||
|
|
||||||
* **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on
|
* **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on
|
||||||
it. For example::
|
it. For example::
|
||||||
|
|
||||||
entry_list = list(Entry.objects.all())
|
entry_list = list(Entry.objects.all())
|
||||||
|
|
||||||
Be warned, though, that this could have a large memory overhead, because
|
Be warned, though, that this could have a large memory overhead, because
|
||||||
Django will load each element of the list into memory. In contrast,
|
Django will load each element of the list into memory. In contrast,
|
||||||
iterating over a ``QuerySet`` will take advantage of your database to
|
iterating over a ``QuerySet`` will take advantage of your database to
|
||||||
load data and instantiate objects only as you need them.
|
load data and instantiate objects only as you need them.
|
||||||
|
|
||||||
* **bool().** Testing a ``QuerySet`` in a boolean context, such as using
|
* **bool().** Testing a ``QuerySet`` in a boolean context, such as using
|
||||||
``bool()``, ``or``, ``and`` or an ``if`` statement, will cause the query
|
``bool()``, ``or``, ``and`` or an ``if`` statement, will cause the query
|
||||||
to be executed. If there is at least one result, the ``QuerySet`` is
|
to be executed. If there is at least one result, the ``QuerySet`` is
|
||||||
``True``, otherwise ``False``. For example::
|
``True``, otherwise ``False``. For example::
|
||||||
|
|
||||||
if Entry.objects.filter(headline="Test"):
|
if Entry.objects.filter(headline="Test"):
|
||||||
print "There is at least one Entry with the headline Test"
|
print "There is at least one Entry with the headline Test"
|
||||||
|
|
||||||
Note: *Don't* use this if all you want to do is determine if at least one
|
Note: *Don't* use this if all you want to do is determine if at least one
|
||||||
result exists, and don't need the actual objects. It's more efficient to
|
result exists, and don't need the actual objects. It's more efficient to
|
||||||
use :meth:`exists() <QuerySet.exists>` (see below).
|
use :meth:`exists() <QuerySet.exists>` (see below).
|
||||||
|
|
||||||
.. _pickling QuerySets:
|
.. _pickling QuerySets:
|
||||||
|
|
||||||
|
@ -411,35 +411,35 @@ Example::
|
||||||
|
|
||||||
A few subtleties that are worth mentioning:
|
A few subtleties that are worth mentioning:
|
||||||
|
|
||||||
* If you have a field called ``foo`` that is a
|
* If you have a field called ``foo`` that is a
|
||||||
:class:`~django.db.models.ForeignKey`, the default ``values()`` call
|
:class:`~django.db.models.ForeignKey`, the default ``values()`` call
|
||||||
will return a dictionary key called ``foo_id``, since this is the name
|
will return a dictionary key called ``foo_id``, since this is the name
|
||||||
of the hidden model attribute that stores the actual value (the ``foo``
|
of the hidden model attribute that stores the actual value (the ``foo``
|
||||||
attribute refers to the related model). When you are calling
|
attribute refers to the related model). When you are calling
|
||||||
``values()`` and passing in field names, you can pass in either ``foo``
|
``values()`` and passing in field names, you can pass in either ``foo``
|
||||||
or ``foo_id`` and you will get back the same thing (the dictionary key
|
or ``foo_id`` and you will get back the same thing (the dictionary key
|
||||||
will match the field name you passed in).
|
will match the field name you passed in).
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
>>> Entry.objects.values()
|
>>> Entry.objects.values()
|
||||||
[{'blog_id': 1, 'headline': u'First Entry', ...}, ...]
|
[{'blog_id': 1, 'headline': u'First Entry', ...}, ...]
|
||||||
|
|
||||||
>>> Entry.objects.values('blog')
|
>>> Entry.objects.values('blog')
|
||||||
[{'blog': 1}, ...]
|
[{'blog': 1}, ...]
|
||||||
|
|
||||||
>>> Entry.objects.values('blog_id')
|
>>> Entry.objects.values('blog_id')
|
||||||
[{'blog_id': 1}, ...]
|
[{'blog_id': 1}, ...]
|
||||||
|
|
||||||
* When using ``values()`` together with :meth:`distinct()`, be aware that
|
* When using ``values()`` together with :meth:`distinct()`, be aware that
|
||||||
ordering can affect the results. See the note in :meth:`distinct` for
|
ordering can affect the results. See the note in :meth:`distinct` for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
* If you use a ``values()`` clause after an :meth:`extra()` call,
|
* If you use a ``values()`` clause after an :meth:`extra()` call,
|
||||||
any fields defined by a ``select`` argument in the :meth:`extra()` must
|
any fields defined by a ``select`` argument in the :meth:`extra()` must
|
||||||
be explicitly included in the ``values()`` call. Any :meth:`extra()` call
|
be explicitly included in the ``values()`` call. Any :meth:`extra()` call
|
||||||
made after a ``values()`` call will have its extra selected fields
|
made after a ``values()`` call will have its extra selected fields
|
||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
A ``ValuesQuerySet`` is useful when you know you're only going to need values
|
A ``ValuesQuerySet`` is useful when you know you're only going to need values
|
||||||
from a small number of the available fields and you won't need the
|
from a small number of the available fields and you won't need the
|
||||||
|
@ -524,11 +524,11 @@ model.
|
||||||
``datetime.datetime`` object in the result list is "truncated" to the given
|
``datetime.datetime`` object in the result list is "truncated" to the given
|
||||||
``type``.
|
``type``.
|
||||||
|
|
||||||
* ``"year"`` returns a list of all distinct year values for the field.
|
* ``"year"`` returns a list of all distinct year values for the field.
|
||||||
* ``"month"`` returns a list of all distinct year/month values for the
|
* ``"month"`` returns a list of all distinct year/month values for the
|
||||||
field.
|
field.
|
||||||
* ``"day"`` returns a list of all distinct year/month/day values for the
|
* ``"day"`` returns a list of all distinct year/month/day values for the
|
||||||
field.
|
field.
|
||||||
|
|
||||||
``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or
|
``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or
|
||||||
``'DESC'``. This specifies how to order the results.
|
``'DESC'``. This specifies how to order the results.
|
||||||
|
@ -832,153 +832,155 @@ principle, so you should avoid them if possible.
|
||||||
Specify one or more of ``params``, ``select``, ``where`` or ``tables``. None
|
Specify one or more of ``params``, ``select``, ``where`` or ``tables``. None
|
||||||
of the arguments is required, but you should use at least one of them.
|
of the arguments is required, but you should use at least one of them.
|
||||||
|
|
||||||
* ``select``
|
* ``select``
|
||||||
The ``select`` argument lets you put extra fields in the ``SELECT``
|
|
||||||
clause. It should be a dictionary mapping attribute names to SQL
|
|
||||||
clauses to use to calculate that attribute.
|
|
||||||
|
|
||||||
Example::
|
The ``select`` argument lets you put extra fields in the ``SELECT``
|
||||||
|
clause. It should be a dictionary mapping attribute names to SQL
|
||||||
|
clauses to use to calculate that attribute.
|
||||||
|
|
||||||
Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
|
Example::
|
||||||
|
|
||||||
As a result, each ``Entry`` object will have an extra attribute,
|
Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
|
||||||
``is_recent``, a boolean representing whether the entry's ``pub_date``
|
|
||||||
is greater than Jan. 1, 2006.
|
|
||||||
|
|
||||||
Django inserts the given SQL snippet directly into the ``SELECT``
|
As a result, each ``Entry`` object will have an extra attribute,
|
||||||
statement, so the resulting SQL of the above example would be something
|
``is_recent``, a boolean representing whether the entry's ``pub_date``
|
||||||
like::
|
is greater than Jan. 1, 2006.
|
||||||
|
|
||||||
SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
|
Django inserts the given SQL snippet directly into the ``SELECT``
|
||||||
FROM blog_entry;
|
statement, so the resulting SQL of the above example would be something
|
||||||
|
like::
|
||||||
|
|
||||||
|
SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
|
||||||
|
FROM blog_entry;
|
||||||
|
|
||||||
|
|
||||||
The next example is more advanced; it does a subquery to give each
|
The next example is more advanced; it does a subquery to give each
|
||||||
resulting ``Blog`` object an ``entry_count`` attribute, an integer count
|
resulting ``Blog`` object an ``entry_count`` attribute, an integer count
|
||||||
of associated ``Entry`` objects::
|
of associated ``Entry`` objects::
|
||||||
|
|
||||||
Blog.objects.extra(
|
Blog.objects.extra(
|
||||||
select={
|
select={
|
||||||
'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
|
'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
In this particular case, we're exploiting the fact that the query will
|
In this particular case, we're exploiting the fact that the query will
|
||||||
already contain the ``blog_blog`` table in its ``FROM`` clause.
|
already contain the ``blog_blog`` table in its ``FROM`` clause.
|
||||||
|
|
||||||
The resulting SQL of the above example would be::
|
The resulting SQL of the above example would be::
|
||||||
|
|
||||||
SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
|
SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
|
||||||
FROM blog_blog;
|
FROM blog_blog;
|
||||||
|
|
||||||
Note that the parentheses required by most database engines around
|
Note that the parentheses required by most database engines around
|
||||||
subqueries are not required in Django's ``select`` clauses. Also note
|
subqueries are not required in Django's ``select`` clauses. Also note
|
||||||
that some database backends, such as some MySQL versions, don't support
|
that some database backends, such as some MySQL versions, don't support
|
||||||
subqueries.
|
subqueries.
|
||||||
|
|
||||||
In some rare cases, you might wish to pass parameters to the SQL
|
In some rare cases, you might wish to pass parameters to the SQL
|
||||||
fragments in ``extra(select=...)``. For this purpose, use the
|
fragments in ``extra(select=...)``. For this purpose, use the
|
||||||
``select_params`` parameter. Since ``select_params`` is a sequence and
|
``select_params`` parameter. Since ``select_params`` is a sequence and
|
||||||
the ``select`` attribute is a dictionary, some care is required so that
|
the ``select`` attribute is a dictionary, some care is required so that
|
||||||
the parameters are matched up correctly with the extra select pieces.
|
the parameters are matched up correctly with the extra select pieces.
|
||||||
In this situation, you should use a
|
In this situation, you should use a
|
||||||
:class:`django.utils.datastructures.SortedDict` for the ``select``
|
:class:`django.utils.datastructures.SortedDict` for the ``select``
|
||||||
value, not just a normal Python dictionary.
|
value, not just a normal Python dictionary.
|
||||||
|
|
||||||
This will work, for example::
|
This will work, for example::
|
||||||
|
|
||||||
Blog.objects.extra(
|
Blog.objects.extra(
|
||||||
select=SortedDict([('a', '%s'), ('b', '%s')]),
|
select=SortedDict([('a', '%s'), ('b', '%s')]),
|
||||||
select_params=('one', 'two'))
|
select_params=('one', 'two'))
|
||||||
|
|
||||||
The only thing to be careful about when using select parameters in
|
The only thing to be careful about when using select parameters in
|
||||||
``extra()`` is to avoid using the substring ``"%%s"`` (that's *two*
|
``extra()`` is to avoid using the substring ``"%%s"`` (that's *two*
|
||||||
percent characters before the ``s``) in the select strings. Django's
|
percent characters before the ``s``) in the select strings. Django's
|
||||||
tracking of parameters looks for ``%s`` and an escaped ``%`` character
|
tracking of parameters looks for ``%s`` and an escaped ``%`` character
|
||||||
like this isn't detected. That will lead to incorrect results.
|
like this isn't detected. That will lead to incorrect results.
|
||||||
|
|
||||||
* ``where`` / ``tables``
|
* ``where`` / ``tables``
|
||||||
You can define explicit SQL ``WHERE`` clauses — perhaps to perform
|
|
||||||
non-explicit joins — by using ``where``. You can manually add tables to
|
|
||||||
the SQL ``FROM`` clause by using ``tables``.
|
|
||||||
|
|
||||||
``where`` and ``tables`` both take a list of strings. All ``where``
|
You can define explicit SQL ``WHERE`` clauses — perhaps to perform
|
||||||
parameters are "AND"ed to any other search criteria.
|
non-explicit joins — by using ``where``. You can manually add tables to
|
||||||
|
the SQL ``FROM`` clause by using ``tables``.
|
||||||
|
|
||||||
Example::
|
``where`` and ``tables`` both take a list of strings. All ``where``
|
||||||
|
parameters are "AND"ed to any other search criteria.
|
||||||
|
|
||||||
Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
|
Example::
|
||||||
|
|
||||||
...translates (roughly) into the following SQL::
|
Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
|
||||||
|
|
||||||
SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);
|
...translates (roughly) into the following SQL::
|
||||||
|
|
||||||
Be careful when using the ``tables`` parameter if you're specifying
|
SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);
|
||||||
tables that are already used in the query. When you add extra tables
|
|
||||||
via the ``tables`` parameter, Django assumes you want that table
|
|
||||||
included an extra time, if it is already included. That creates a
|
|
||||||
problem, since the table name will then be given an alias. If a table
|
|
||||||
appears multiple times in an SQL statement, the second and subsequent
|
|
||||||
occurrences must use aliases so the database can tell them apart. If
|
|
||||||
you're referring to the extra table you added in the extra ``where``
|
|
||||||
parameter this is going to cause errors.
|
|
||||||
|
|
||||||
Normally you'll only be adding extra tables that don't already appear
|
Be careful when using the ``tables`` parameter if you're specifying
|
||||||
in the query. However, if the case outlined above does occur, there are
|
tables that are already used in the query. When you add extra tables
|
||||||
a few solutions. First, see if you can get by without including the
|
via the ``tables`` parameter, Django assumes you want that table
|
||||||
extra table and use the one already in the query. If that isn't
|
included an extra time, if it is already included. That creates a
|
||||||
possible, put your ``extra()`` call at the front of the queryset
|
problem, since the table name will then be given an alias. If a table
|
||||||
construction so that your table is the first use of that table.
|
appears multiple times in an SQL statement, the second and subsequent
|
||||||
Finally, if all else fails, look at the query produced and rewrite your
|
occurrences must use aliases so the database can tell them apart. If
|
||||||
``where`` addition to use the alias given to your extra table. The
|
you're referring to the extra table you added in the extra ``where``
|
||||||
alias will be the same each time you construct the queryset in the same
|
parameter this is going to cause errors.
|
||||||
way, so you can rely upon the alias name to not change.
|
|
||||||
|
|
||||||
* ``order_by``
|
Normally you'll only be adding extra tables that don't already appear
|
||||||
|
in the query. However, if the case outlined above does occur, there are
|
||||||
|
a few solutions. First, see if you can get by without including the
|
||||||
|
extra table and use the one already in the query. If that isn't
|
||||||
|
possible, put your ``extra()`` call at the front of the queryset
|
||||||
|
construction so that your table is the first use of that table.
|
||||||
|
Finally, if all else fails, look at the query produced and rewrite your
|
||||||
|
``where`` addition to use the alias given to your extra table. The
|
||||||
|
alias will be the same each time you construct the queryset in the same
|
||||||
|
way, so you can rely upon the alias name to not change.
|
||||||
|
|
||||||
If you need to order the resulting queryset using some of the new
|
* ``order_by``
|
||||||
fields or tables you have included via ``extra()`` use the ``order_by``
|
|
||||||
parameter to ``extra()`` and pass in a sequence of strings. These
|
|
||||||
strings should either be model fields (as in the normal
|
|
||||||
:meth:`order_by()` method on querysets), of the form
|
|
||||||
``table_name.column_name`` or an alias for a column that you specified
|
|
||||||
in the ``select`` parameter to ``extra()``.
|
|
||||||
|
|
||||||
For example::
|
If you need to order the resulting queryset using some of the new
|
||||||
|
fields or tables you have included via ``extra()`` use the ``order_by``
|
||||||
|
parameter to ``extra()`` and pass in a sequence of strings. These
|
||||||
|
strings should either be model fields (as in the normal
|
||||||
|
:meth:`order_by()` method on querysets), of the form
|
||||||
|
``table_name.column_name`` or an alias for a column that you specified
|
||||||
|
in the ``select`` parameter to ``extra()``.
|
||||||
|
|
||||||
q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
|
For example::
|
||||||
q = q.extra(order_by = ['-is_recent'])
|
|
||||||
|
|
||||||
This would sort all the items for which ``is_recent`` is true to the
|
q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
|
||||||
front of the result set (``True`` sorts before ``False`` in a
|
q = q.extra(order_by = ['-is_recent'])
|
||||||
descending ordering).
|
|
||||||
|
|
||||||
This shows, by the way, that you can make multiple calls to ``extra()``
|
This would sort all the items for which ``is_recent`` is true to the
|
||||||
and it will behave as you expect (adding new constraints each time).
|
front of the result set (``True`` sorts before ``False`` in a
|
||||||
|
descending ordering).
|
||||||
|
|
||||||
* ``params``
|
This shows, by the way, that you can make multiple calls to ``extra()``
|
||||||
|
and it will behave as you expect (adding new constraints each time).
|
||||||
|
|
||||||
The ``where`` parameter described above may use standard Python
|
* ``params``
|
||||||
database string placeholders — ``'%s'`` to indicate parameters the
|
|
||||||
database engine should automatically quote. The ``params`` argument is
|
|
||||||
a list of any extra parameters to be substituted.
|
|
||||||
|
|
||||||
Example::
|
The ``where`` parameter described above may use standard Python
|
||||||
|
database string placeholders — ``'%s'`` to indicate parameters the
|
||||||
|
database engine should automatically quote. The ``params`` argument is
|
||||||
|
a list of any extra parameters to be substituted.
|
||||||
|
|
||||||
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
|
Example::
|
||||||
|
|
||||||
Always use ``params`` instead of embedding values directly into
|
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
|
||||||
``where`` because ``params`` will ensure values are quoted correctly
|
|
||||||
according to your particular backend. For example, quotes will be
|
|
||||||
escaped correctly.
|
|
||||||
|
|
||||||
Bad::
|
Always use ``params`` instead of embedding values directly into
|
||||||
|
``where`` because ``params`` will ensure values are quoted correctly
|
||||||
|
according to your particular backend. For example, quotes will be
|
||||||
|
escaped correctly.
|
||||||
|
|
||||||
Entry.objects.extra(where=["headline='Lennon'"])
|
Bad::
|
||||||
|
|
||||||
Good::
|
Entry.objects.extra(where=["headline='Lennon'"])
|
||||||
|
|
||||||
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
|
Good::
|
||||||
|
|
||||||
|
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
|
||||||
|
|
||||||
defer
|
defer
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -1304,11 +1306,11 @@ are)::
|
||||||
|
|
||||||
This has a number of caveats though:
|
This has a number of caveats though:
|
||||||
|
|
||||||
* The model's ``save()`` method will not be called, and the ``pre_save`` and
|
* The model's ``save()`` method will not be called, and the ``pre_save`` and
|
||||||
``post_save`` signals will not be sent.
|
``post_save`` signals will not be sent.
|
||||||
* It does not work with child models in a multi-table inheritance scenario.
|
* It does not work with child models in a multi-table inheritance scenario.
|
||||||
* If the model's primary key is an :class:`~django.db.models.AutoField` it
|
* If the model's primary key is an :class:`~django.db.models.AutoField` it
|
||||||
does not retrieve and set the primary key attribute, as ``save()`` does.
|
does not retrieve and set the primary key attribute, as ``save()`` does.
|
||||||
|
|
||||||
count
|
count
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -2059,8 +2061,8 @@ Avg
|
||||||
|
|
||||||
Returns the mean value of the given field.
|
Returns the mean value of the given field.
|
||||||
|
|
||||||
* Default alias: ``<field>__avg``
|
* Default alias: ``<field>__avg``
|
||||||
* Return type: float
|
* Return type: float
|
||||||
|
|
||||||
Count
|
Count
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -2069,8 +2071,8 @@ Count
|
||||||
|
|
||||||
Returns the number of objects that are related through the provided field.
|
Returns the number of objects that are related through the provided field.
|
||||||
|
|
||||||
* Default alias: ``<field>__count``
|
* Default alias: ``<field>__count``
|
||||||
* Return type: integer
|
* Return type: integer
|
||||||
|
|
||||||
Has one optional argument:
|
Has one optional argument:
|
||||||
|
|
||||||
|
@ -2086,8 +2088,8 @@ Max
|
||||||
|
|
||||||
Returns the maximum value of the given field.
|
Returns the maximum value of the given field.
|
||||||
|
|
||||||
* Default alias: ``<field>__max``
|
* Default alias: ``<field>__max``
|
||||||
* Return type: same as input field
|
* Return type: same as input field
|
||||||
|
|
||||||
Min
|
Min
|
||||||
~~~
|
~~~
|
||||||
|
@ -2096,8 +2098,8 @@ Min
|
||||||
|
|
||||||
Returns the minimum value of the given field.
|
Returns the minimum value of the given field.
|
||||||
|
|
||||||
* Default alias: ``<field>__min``
|
* Default alias: ``<field>__min``
|
||||||
* Return type: same as input field
|
* Return type: same as input field
|
||||||
|
|
||||||
StdDev
|
StdDev
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
@ -2106,8 +2108,8 @@ StdDev
|
||||||
|
|
||||||
Returns the standard deviation of the data in the provided field.
|
Returns the standard deviation of the data in the provided field.
|
||||||
|
|
||||||
* Default alias: ``<field>__stddev``
|
* Default alias: ``<field>__stddev``
|
||||||
* Return type: float
|
* Return type: float
|
||||||
|
|
||||||
Has one optional argument:
|
Has one optional argument:
|
||||||
|
|
||||||
|
@ -2129,8 +2131,8 @@ Sum
|
||||||
|
|
||||||
Computes the sum of all values of the given field.
|
Computes the sum of all values of the given field.
|
||||||
|
|
||||||
* Default alias: ``<field>__sum``
|
* Default alias: ``<field>__sum``
|
||||||
* Return type: same as input field
|
* Return type: same as input field
|
||||||
|
|
||||||
Variance
|
Variance
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
@ -2139,8 +2141,8 @@ Variance
|
||||||
|
|
||||||
Returns the variance of the data in the provided field.
|
Returns the variance of the data in the provided field.
|
||||||
|
|
||||||
* Default alias: ``<field>__variance``
|
* Default alias: ``<field>__variance``
|
||||||
* Return type: float
|
* Return type: float
|
||||||
|
|
||||||
Has one optional argument:
|
Has one optional argument:
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ Caveats with support of certain databases
|
||||||
Django attempts to support as many features as possible on all database
|
Django attempts to support as many features as possible on all database
|
||||||
backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It's a good idea to checkout our :doc:`notes on supported database </ref/databases>`:
|
backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It's a good idea to checkout our :doc:`notes on supported database </ref/databases>`:
|
||||||
|
|
||||||
- :ref:`mysql-notes`
|
- :ref:`mysql-notes`
|
||||||
- :ref:`sqlite-notes`
|
- :ref:`sqlite-notes`
|
||||||
- :ref:`oracle-notes`
|
- :ref:`oracle-notes`
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@ Overview
|
||||||
|
|
||||||
The auth system consists of:
|
The auth system consists of:
|
||||||
|
|
||||||
* Users
|
* Users
|
||||||
* Permissions: Binary (yes/no) flags designating whether a user may perform
|
* Permissions: Binary (yes/no) flags designating whether a user may perform
|
||||||
a certain task.
|
a certain task.
|
||||||
* Groups: A generic way of applying labels and permissions to more than one
|
* Groups: A generic way of applying labels and permissions to more than one
|
||||||
user.
|
user.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
@ -26,11 +26,11 @@ Installation
|
||||||
Authentication support is bundled as a Django application in
|
Authentication support is bundled as a Django application in
|
||||||
``django.contrib.auth``. To install it, do the following:
|
``django.contrib.auth``. To install it, do the following:
|
||||||
|
|
||||||
1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
|
1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
|
||||||
your :setting:`INSTALLED_APPS` setting.
|
your :setting:`INSTALLED_APPS` setting.
|
||||||
(The :class:`~django.contrib.auth.models.Permission` model in
|
(The :class:`~django.contrib.auth.models.Permission` model in
|
||||||
:mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.)
|
:mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.)
|
||||||
2. Run the command ``manage.py syncdb``.
|
2. Run the command ``manage.py syncdb``.
|
||||||
|
|
||||||
Note that the default :file:`settings.py` file created by
|
Note that the default :file:`settings.py` file created by
|
||||||
:djadmin:`django-admin.py startproject <startproject>` includes
|
:djadmin:`django-admin.py startproject <startproject>` includes
|
||||||
|
@ -303,10 +303,10 @@ Manager functions
|
||||||
allowed characters. (Note that the default value of ``allowed_chars``
|
allowed characters. (Note that the default value of ``allowed_chars``
|
||||||
doesn't contain letters that can cause user confusion, including:
|
doesn't contain letters that can cause user confusion, including:
|
||||||
|
|
||||||
* ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
|
* ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
|
||||||
letter L, uppercase letter i, and the number one)
|
letter L, uppercase letter i, and the number one)
|
||||||
* ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
|
* ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
|
||||||
and zero)
|
and zero)
|
||||||
|
|
||||||
Basic usage
|
Basic usage
|
||||||
-----------
|
-----------
|
||||||
|
@ -715,29 +715,29 @@ Sent when a user logs in successfully.
|
||||||
|
|
||||||
Arguments sent with this signal:
|
Arguments sent with this signal:
|
||||||
|
|
||||||
``sender``
|
``sender``
|
||||||
As above: the class of the user that just logged in.
|
As above: the class of the user that just logged in.
|
||||||
|
|
||||||
``request``
|
``request``
|
||||||
The current :class:`~django.http.HttpRequest` instance.
|
The current :class:`~django.http.HttpRequest` instance.
|
||||||
|
|
||||||
``user``
|
``user``
|
||||||
The user instance that just logged in.
|
The user instance that just logged in.
|
||||||
|
|
||||||
.. data:: django.contrib.auth.signals.user_logged_out
|
.. data:: django.contrib.auth.signals.user_logged_out
|
||||||
|
|
||||||
Sent when the logout method is called.
|
Sent when the logout method is called.
|
||||||
|
|
||||||
``sender``
|
``sender``
|
||||||
As above: the class of the user that just logged out or ``None``
|
As above: the class of the user that just logged out or ``None``
|
||||||
if the user was not authenticated.
|
if the user was not authenticated.
|
||||||
|
|
||||||
``request``
|
``request``
|
||||||
The current :class:`~django.http.HttpRequest` instance.
|
The current :class:`~django.http.HttpRequest` instance.
|
||||||
|
|
||||||
``user``
|
``user``
|
||||||
The user instance that just logged out or ``None`` if the
|
The user instance that just logged out or ``None`` if the
|
||||||
user was not authenticated.
|
user was not authenticated.
|
||||||
|
|
||||||
Limiting access to logged-in users
|
Limiting access to logged-in users
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
@ -830,38 +830,38 @@ The login_required decorator
|
||||||
|
|
||||||
Here's what ``django.contrib.auth.views.login`` does:
|
Here's what ``django.contrib.auth.views.login`` does:
|
||||||
|
|
||||||
* If called via ``GET``, it displays a login form that POSTs to the
|
* If called via ``GET``, it displays a login form that POSTs to the
|
||||||
same URL. More on this in a bit.
|
same URL. More on this in a bit.
|
||||||
|
|
||||||
* If called via ``POST``, it tries to log the user in. If login is
|
* If called via ``POST``, it tries to log the user in. If login is
|
||||||
successful, the view redirects to the URL specified in ``next``. If
|
successful, the view redirects to the URL specified in ``next``. If
|
||||||
``next`` isn't provided, it redirects to
|
``next`` isn't provided, it redirects to
|
||||||
:setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>` (which
|
:setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>` (which
|
||||||
defaults to ``/accounts/profile/``). If login isn't successful, it
|
defaults to ``/accounts/profile/``). If login isn't successful, it
|
||||||
redisplays the login form.
|
redisplays the login form.
|
||||||
|
|
||||||
It's your responsibility to provide the login form in a template called
|
It's your responsibility to provide the login form in a template called
|
||||||
``registration/login.html`` by default. This template gets passed four
|
``registration/login.html`` by default. This template gets passed four
|
||||||
template context variables:
|
template context variables:
|
||||||
|
|
||||||
* ``form``: A :class:`~django.forms.Form` object representing the login
|
* ``form``: A :class:`~django.forms.Form` object representing the login
|
||||||
form. See the :doc:`forms documentation </topics/forms/index>` for
|
form. See the :doc:`forms documentation </topics/forms/index>` for
|
||||||
more on ``Form`` objects.
|
more on ``Form`` objects.
|
||||||
|
|
||||||
* ``next``: The URL to redirect to after successful login. This may
|
* ``next``: The URL to redirect to after successful login. This may
|
||||||
contain a query string, too.
|
contain a query string, too.
|
||||||
|
|
||||||
* ``site``: The current :class:`~django.contrib.sites.models.Site`,
|
* ``site``: The current :class:`~django.contrib.sites.models.Site`,
|
||||||
according to the :setting:`SITE_ID` setting. If you don't have the
|
according to the :setting:`SITE_ID` setting. If you don't have the
|
||||||
site framework installed, this will be set to an instance of
|
site framework installed, this will be set to an instance of
|
||||||
:class:`~django.contrib.sites.models.RequestSite`, which derives the
|
:class:`~django.contrib.sites.models.RequestSite`, which derives the
|
||||||
site name and domain from the current
|
site name and domain from the current
|
||||||
:class:`~django.http.HttpRequest`.
|
:class:`~django.http.HttpRequest`.
|
||||||
|
|
||||||
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
||||||
framework installed, this will be set to the value of
|
framework installed, this will be set to the value of
|
||||||
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
||||||
For more on sites, see :doc:`/ref/contrib/sites`.
|
For more on sites, see :doc:`/ref/contrib/sites`.
|
||||||
|
|
||||||
If you'd prefer not to call the template :file:`registration/login.html`,
|
If you'd prefer not to call the template :file:`registration/login.html`,
|
||||||
you can pass the ``template_name`` parameter via the extra arguments to
|
you can pass the ``template_name`` parameter via the extra arguments to
|
||||||
|
@ -950,31 +950,31 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``next_page``: The URL to redirect to after logout.
|
* ``next_page``: The URL to redirect to after logout.
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to display after
|
* ``template_name``: The full name of a template to display after
|
||||||
logging the user out. Defaults to
|
logging the user out. Defaults to
|
||||||
:file:`registration/logged_out.html` if no argument is supplied.
|
:file:`registration/logged_out.html` if no argument is supplied.
|
||||||
|
|
||||||
* ``redirect_field_name``: The name of a ``GET`` field containing the
|
* ``redirect_field_name``: The name of a ``GET`` field containing the
|
||||||
URL to redirect to after log out. Overrides ``next_page`` if the given
|
URL to redirect to after log out. Overrides ``next_page`` if the given
|
||||||
``GET`` parameter is passed.
|
``GET`` parameter is passed.
|
||||||
|
|
||||||
**Template context:**
|
**Template context:**
|
||||||
|
|
||||||
* ``title``: The string "Logged out", localized.
|
* ``title``: The string "Logged out", localized.
|
||||||
|
|
||||||
* ``site``: The current :class:`~django.contrib.sites.models.Site`,
|
* ``site``: The current :class:`~django.contrib.sites.models.Site`,
|
||||||
according to the :setting:`SITE_ID` setting. If you don't have the
|
according to the :setting:`SITE_ID` setting. If you don't have the
|
||||||
site framework installed, this will be set to an instance of
|
site framework installed, this will be set to an instance of
|
||||||
:class:`~django.contrib.sites.models.RequestSite`, which derives the
|
:class:`~django.contrib.sites.models.RequestSite`, which derives the
|
||||||
site name and domain from the current
|
site name and domain from the current
|
||||||
:class:`~django.http.HttpRequest`.
|
:class:`~django.http.HttpRequest`.
|
||||||
|
|
||||||
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
||||||
framework installed, this will be set to the value of
|
framework installed, this will be set to the value of
|
||||||
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
||||||
For more on sites, see :doc:`/ref/contrib/sites`.
|
For more on sites, see :doc:`/ref/contrib/sites`.
|
||||||
|
|
||||||
.. function:: logout_then_login(request[, login_url])
|
.. function:: logout_then_login(request[, login_url])
|
||||||
|
|
||||||
|
@ -984,8 +984,8 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to.
|
* ``login_url``: The URL of the login page to redirect to.
|
||||||
Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
|
Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
|
||||||
|
|
||||||
.. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
|
.. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
|
||||||
|
|
||||||
|
@ -995,23 +995,23 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to use for
|
* ``template_name``: The full name of a template to use for
|
||||||
displaying the password change form. Defaults to
|
displaying the password change form. Defaults to
|
||||||
:file:`registration/password_change_form.html` if not supplied.
|
:file:`registration/password_change_form.html` if not supplied.
|
||||||
|
|
||||||
* ``post_change_redirect``: The URL to redirect to after a successful
|
* ``post_change_redirect``: The URL to redirect to after a successful
|
||||||
password change.
|
password change.
|
||||||
|
|
||||||
.. versionadded:: 1.2
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
* ``password_change_form``: A custom "change password" form which must
|
* ``password_change_form``: A custom "change password" form which must
|
||||||
accept a ``user`` keyword argument. The form is responsible for
|
accept a ``user`` keyword argument. The form is responsible for
|
||||||
actually changing the user's password. Defaults to
|
actually changing the user's password. Defaults to
|
||||||
:class:`~django.contrib.auth.forms.PasswordChangeForm`.
|
:class:`~django.contrib.auth.forms.PasswordChangeForm`.
|
||||||
|
|
||||||
**Template context:**
|
**Template context:**
|
||||||
|
|
||||||
* ``form``: The password change form (see ``password_change_form`` above).
|
* ``form``: The password change form (see ``password_change_form`` above).
|
||||||
|
|
||||||
.. function:: password_change_done(request[, template_name])
|
.. function:: password_change_done(request[, template_name])
|
||||||
|
|
||||||
|
@ -1021,9 +1021,9 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to use.
|
* ``template_name``: The full name of a template to use.
|
||||||
Defaults to :file:`registration/password_change_done.html` if not
|
Defaults to :file:`registration/password_change_done.html` if not
|
||||||
supplied.
|
supplied.
|
||||||
|
|
||||||
.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
|
.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
|
||||||
|
|
||||||
|
@ -1044,60 +1044,60 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to use for
|
* ``template_name``: The full name of a template to use for
|
||||||
displaying the password reset form. Defaults to
|
displaying the password reset form. Defaults to
|
||||||
:file:`registration/password_reset_form.html` if not supplied.
|
:file:`registration/password_reset_form.html` if not supplied.
|
||||||
|
|
||||||
* ``email_template_name``: The full name of a template to use for
|
* ``email_template_name``: The full name of a template to use for
|
||||||
generating the email with the new password. Defaults to
|
generating the email with the new password. Defaults to
|
||||||
:file:`registration/password_reset_email.html` if not supplied.
|
:file:`registration/password_reset_email.html` if not supplied.
|
||||||
|
|
||||||
* ``subject_template_name``: The full name of a template to use for
|
* ``subject_template_name``: The full name of a template to use for
|
||||||
the subject of the email with the new password. Defaults
|
the subject of the email with the new password. Defaults
|
||||||
to :file:`registration/password_reset_subject.txt` if not supplied.
|
to :file:`registration/password_reset_subject.txt` if not supplied.
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
* ``password_reset_form``: Form that will be used to set the password.
|
* ``password_reset_form``: Form that will be used to set the password.
|
||||||
Defaults to :class:`~django.contrib.auth.forms.PasswordResetForm`.
|
Defaults to :class:`~django.contrib.auth.forms.PasswordResetForm`.
|
||||||
|
|
||||||
* ``token_generator``: Instance of the class to check the password. This
|
* ``token_generator``: Instance of the class to check the password. This
|
||||||
will default to ``default_token_generator``, it's an instance of
|
will default to ``default_token_generator``, it's an instance of
|
||||||
``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
|
``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
|
||||||
|
|
||||||
* ``post_reset_redirect``: The URL to redirect to after a successful
|
* ``post_reset_redirect``: The URL to redirect to after a successful
|
||||||
password change.
|
password change.
|
||||||
|
|
||||||
* ``from_email``: A valid email address. By default Django uses
|
* ``from_email``: A valid email address. By default Django uses
|
||||||
the :setting:`DEFAULT_FROM_EMAIL`.
|
the :setting:`DEFAULT_FROM_EMAIL`.
|
||||||
|
|
||||||
**Template context:**
|
**Template context:**
|
||||||
|
|
||||||
* ``form``: The form (see ``password_reset_form`` above) for resetting
|
* ``form``: The form (see ``password_reset_form`` above) for resetting
|
||||||
the user's password.
|
the user's password.
|
||||||
|
|
||||||
**Email template context:**
|
**Email template context:**
|
||||||
|
|
||||||
* ``email``: An alias for ``user.email``
|
* ``email``: An alias for ``user.email``
|
||||||
|
|
||||||
* ``user``: The current :class:`~django.contrib.auth.models.User`,
|
* ``user``: The current :class:`~django.contrib.auth.models.User`,
|
||||||
according to the ``email`` form field. Only active users are able to
|
according to the ``email`` form field. Only active users are able to
|
||||||
reset their passwords (``User.is_active is True``).
|
reset their passwords (``User.is_active is True``).
|
||||||
|
|
||||||
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
* ``site_name``: An alias for ``site.name``. If you don't have the site
|
||||||
framework installed, this will be set to the value of
|
framework installed, this will be set to the value of
|
||||||
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
|
||||||
For more on sites, see :doc:`/ref/contrib/sites`.
|
For more on sites, see :doc:`/ref/contrib/sites`.
|
||||||
|
|
||||||
* ``domain``: An alias for ``site.domain``. If you don't have the site
|
* ``domain``: An alias for ``site.domain``. If you don't have the site
|
||||||
framework installed, this will be set to the value of
|
framework installed, this will be set to the value of
|
||||||
``request.get_host()``.
|
``request.get_host()``.
|
||||||
|
|
||||||
* ``protocol``: http or https
|
* ``protocol``: http or https
|
||||||
|
|
||||||
* ``uid``: The user's id encoded in base 36.
|
* ``uid``: The user's id encoded in base 36.
|
||||||
|
|
||||||
* ``token``: Token to check that the password is valid.
|
* ``token``: Token to check that the password is valid.
|
||||||
|
|
||||||
Sample ``registration/password_reset_email.html`` (email body template):
|
Sample ``registration/password_reset_email.html`` (email body template):
|
||||||
|
|
||||||
|
@ -1121,9 +1121,9 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to use.
|
* ``template_name``: The full name of a template to use.
|
||||||
Defaults to :file:`registration/password_reset_done.html` if not
|
Defaults to :file:`registration/password_reset_done.html` if not
|
||||||
supplied.
|
supplied.
|
||||||
|
|
||||||
.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])
|
.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])
|
||||||
|
|
||||||
|
@ -1133,31 +1133,31 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``uidb36``: The user's id encoded in base 36. Defaults to ``None``.
|
* ``uidb36``: The user's id encoded in base 36. Defaults to ``None``.
|
||||||
|
|
||||||
* ``token``: Token to check that the password is valid. Defaults to
|
* ``token``: Token to check that the password is valid. Defaults to
|
||||||
``None``.
|
``None``.
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to display the confirm
|
* ``template_name``: The full name of a template to display the confirm
|
||||||
password view. Default value is :file:`registration/password_reset_confirm.html`.
|
password view. Default value is :file:`registration/password_reset_confirm.html`.
|
||||||
|
|
||||||
* ``token_generator``: Instance of the class to check the password. This
|
* ``token_generator``: Instance of the class to check the password. This
|
||||||
will default to ``default_token_generator``, it's an instance of
|
will default to ``default_token_generator``, it's an instance of
|
||||||
``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
|
``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
|
||||||
|
|
||||||
* ``set_password_form``: Form that will be used to set the password.
|
* ``set_password_form``: Form that will be used to set the password.
|
||||||
Defaults to :class:`~django.contrib.auth.forms.SetPasswordForm`
|
Defaults to :class:`~django.contrib.auth.forms.SetPasswordForm`
|
||||||
|
|
||||||
* ``post_reset_redirect``: URL to redirect after the password reset
|
* ``post_reset_redirect``: URL to redirect after the password reset
|
||||||
done. Defaults to ``None``.
|
done. Defaults to ``None``.
|
||||||
|
|
||||||
**Template context:**
|
**Template context:**
|
||||||
|
|
||||||
* ``form``: The form (see ``set_password_form`` above) for setting the
|
* ``form``: The form (see ``set_password_form`` above) for setting the
|
||||||
new user's password.
|
new user's password.
|
||||||
|
|
||||||
* ``validlink``: Boolean, True if the link (combination of uidb36 and
|
* ``validlink``: Boolean, True if the link (combination of uidb36 and
|
||||||
token) is valid or unused yet.
|
token) is valid or unused yet.
|
||||||
|
|
||||||
.. function:: password_reset_complete(request[,template_name])
|
.. function:: password_reset_complete(request[,template_name])
|
||||||
|
|
||||||
|
@ -1168,8 +1168,8 @@ includes a few other useful built-in views located in
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``template_name``: The full name of a template to display the view.
|
* ``template_name``: The full name of a template to display the view.
|
||||||
Defaults to :file:`registration/password_reset_complete.html`.
|
Defaults to :file:`registration/password_reset_complete.html`.
|
||||||
|
|
||||||
Helper functions
|
Helper functions
|
||||||
----------------
|
----------------
|
||||||
|
@ -1183,16 +1183,16 @@ Helper functions
|
||||||
|
|
||||||
**Required arguments:**
|
**Required arguments:**
|
||||||
|
|
||||||
* ``next``: The URL to redirect to after a successful login.
|
* ``next``: The URL to redirect to after a successful login.
|
||||||
|
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to.
|
* ``login_url``: The URL of the login page to redirect to.
|
||||||
Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
|
Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
|
||||||
|
|
||||||
* ``redirect_field_name``: The name of a ``GET`` field containing the
|
* ``redirect_field_name``: The name of a ``GET`` field containing the
|
||||||
URL to redirect to after log out. Overrides ``next`` if the given
|
URL to redirect to after log out. Overrides ``next`` if the given
|
||||||
``GET`` parameter is passed.
|
``GET`` parameter is passed.
|
||||||
|
|
||||||
Built-in forms
|
Built-in forms
|
||||||
--------------
|
--------------
|
||||||
|
@ -1354,13 +1354,13 @@ code.
|
||||||
|
|
||||||
The Django admin site uses permissions as follows:
|
The Django admin site uses permissions as follows:
|
||||||
|
|
||||||
* Access to view the "add" form and add an object is limited to users with
|
* Access to view the "add" form and add an object is limited to users with
|
||||||
the "add" permission for that type of object.
|
the "add" permission for that type of object.
|
||||||
* Access to view the change list, view the "change" form and change an
|
* Access to view the change list, view the "change" form and change an
|
||||||
object is limited to users with the "change" permission for that type of
|
object is limited to users with the "change" permission for that type of
|
||||||
object.
|
object.
|
||||||
* Access to delete an object is limited to users with the "delete"
|
* Access to delete an object is limited to users with the "delete"
|
||||||
permission for that type of object.
|
permission for that type of object.
|
||||||
|
|
||||||
Permissions are set globally per type of object, not per specific object
|
Permissions are set globally per type of object, not per specific object
|
||||||
instance. For example, it's possible to say "Mary may change news stories," but
|
instance. For example, it's possible to say "Mary may change news stories," but
|
||||||
|
@ -1389,9 +1389,9 @@ Assuming you have an application with an
|
||||||
:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
|
:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
|
||||||
to test for basic permissions you should use:
|
to test for basic permissions you should use:
|
||||||
|
|
||||||
* add: ``user.has_perm('foo.add_bar')``
|
* add: ``user.has_perm('foo.add_bar')``
|
||||||
* change: ``user.has_perm('foo.change_bar')``
|
* change: ``user.has_perm('foo.change_bar')``
|
||||||
* delete: ``user.has_perm('foo.delete_bar')``
|
* delete: ``user.has_perm('foo.delete_bar')``
|
||||||
|
|
||||||
.. _custom-permissions:
|
.. _custom-permissions:
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ Use a dot (``.``) to access attributes of a variable.
|
||||||
Technically, when the template system encounters a dot, it tries the
|
Technically, when the template system encounters a dot, it tries the
|
||||||
following lookups, in this order:
|
following lookups, in this order:
|
||||||
|
|
||||||
* Dictionary lookup
|
* Dictionary lookup
|
||||||
* Attribute lookup
|
* Attribute lookup
|
||||||
* Method call
|
* Method call
|
||||||
* List-index lookup
|
* List-index lookup
|
||||||
|
|
||||||
In the above example, ``{{ section.title }}`` will be replaced with the
|
In the above example, ``{{ section.title }}`` will be replaced with the
|
||||||
``title`` attribute of the ``section`` object.
|
``title`` attribute of the ``section`` object.
|
||||||
|
@ -129,32 +129,32 @@ them in the :ref:`built-in filter reference <ref-templates-builtins-filters>`.
|
||||||
To give you a taste of what's available, here are some of the more commonly
|
To give you a taste of what's available, here are some of the more commonly
|
||||||
used template filters:
|
used template filters:
|
||||||
|
|
||||||
:tfilter:`default`
|
:tfilter:`default`
|
||||||
If a variable is false or empty, use given default. Otherwise, use the
|
If a variable is false or empty, use given default. Otherwise, use the
|
||||||
value of the variable
|
value of the variable
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
{{ value|default:"nothing" }}
|
{{ value|default:"nothing" }}
|
||||||
|
|
||||||
If ``value`` isn't provided or is empty, the above will display
|
If ``value`` isn't provided or is empty, the above will display
|
||||||
"``nothing``".
|
"``nothing``".
|
||||||
|
|
||||||
:tfilter:`length`
|
:tfilter:`length`
|
||||||
Returns the length of the value. This works for both strings and lists;
|
Returns the length of the value. This works for both strings and lists;
|
||||||
for example::
|
for example::
|
||||||
|
|
||||||
{{ value|length }}
|
{{ value|length }}
|
||||||
|
|
||||||
If ``value`` is ``['a', 'b', 'c', 'd']``, the output will be ``4``.
|
If ``value`` is ``['a', 'b', 'c', 'd']``, the output will be ``4``.
|
||||||
|
|
||||||
:tfilter:`striptags`
|
:tfilter:`striptags`
|
||||||
Strips all [X]HTML tags. For example::
|
Strips all [X]HTML tags. For example::
|
||||||
|
|
||||||
{{ value|striptags }}
|
{{ value|striptags }}
|
||||||
|
|
||||||
If ``value`` is ``"<b>Joel</b> <button>is</button> a
|
If ``value`` is ``"<b>Joel</b> <button>is</button> a
|
||||||
<span>slug</span>"``, the output will be ``"Joel is a slug"``.
|
<span>slug</span>"``, the output will be ``"Joel is a slug"``.
|
||||||
|
|
||||||
Again, these are just a few examples; see the :ref:`built-in filter reference
|
Again, these are just a few examples; see the :ref:`built-in filter reference
|
||||||
<ref-templates-builtins-filters>` for the complete list.
|
<ref-templates-builtins-filters>` for the complete list.
|
||||||
|
@ -183,40 +183,40 @@ them in the :ref:`built-in tag reference <ref-templates-builtins-tags>`. To give
|
||||||
you a taste of what's available, here are some of the more commonly used
|
you a taste of what's available, here are some of the more commonly used
|
||||||
tags:
|
tags:
|
||||||
|
|
||||||
:ttag:`for`
|
:ttag:`for`
|
||||||
Loop over each item in an array. For example, to display a list of athletes
|
Loop over each item in an array. For example, to display a list of athletes
|
||||||
provided in ``athlete_list``::
|
provided in ``athlete_list``::
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{% for athlete in athlete_list %}
|
{% for athlete in athlete_list %}
|
||||||
<li>{{ athlete.name }}</li>
|
<li>{{ athlete.name }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
:ttag:`if` and ``else``
|
:ttag:`if` and ``else``
|
||||||
Evaluates a variable, and if that variable is "true" the contents of the
|
Evaluates a variable, and if that variable is "true" the contents of the
|
||||||
block are displayed::
|
block are displayed::
|
||||||
|
|
||||||
{% if athlete_list %}
|
{% if athlete_list %}
|
||||||
Number of athletes: {{ athlete_list|length }}
|
Number of athletes: {{ athlete_list|length }}
|
||||||
{% else %}
|
{% else %}
|
||||||
No athletes.
|
No athletes.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
In the above, if ``athlete_list`` is not empty, the number of athletes
|
In the above, if ``athlete_list`` is not empty, the number of athletes
|
||||||
will be displayed by the ``{{ athlete_list|length }}`` variable.
|
will be displayed by the ``{{ athlete_list|length }}`` variable.
|
||||||
|
|
||||||
You can also use filters and various operators in the :ttag:`if` tag::
|
You can also use filters and various operators in the :ttag:`if` tag::
|
||||||
|
|
||||||
{% if athlete_list|length > 1 %}
|
{% if athlete_list|length > 1 %}
|
||||||
Team: {% for athlete in athlete_list %} ... {% endfor %}
|
Team: {% for athlete in athlete_list %} ... {% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Athlete: {{ athlete_list.0.name }}
|
Athlete: {{ athlete_list.0.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
:ttag:`block` and :ttag:`extends`
|
:ttag:`block` and :ttag:`extends`
|
||||||
Set up `template inheritance`_ (see below), a powerful way
|
Set up `template inheritance`_ (see below), a powerful way
|
||||||
of cutting down on "boilerplate" in templates.
|
of cutting down on "boilerplate" in templates.
|
||||||
|
|
||||||
Again, the above is only a selection of the whole list; see the :ref:`built-in
|
Again, the above is only a selection of the whole list; see the :ref:`built-in
|
||||||
tag reference <ref-templates-builtins-tags>` for the complete list.
|
tag reference <ref-templates-builtins-tags>` for the complete list.
|
||||||
|
@ -344,49 +344,49 @@ tag in a parent template is always used as a fallback.
|
||||||
You can use as many levels of inheritance as needed. One common way of using
|
You can use as many levels of inheritance as needed. One common way of using
|
||||||
inheritance is the following three-level approach:
|
inheritance is the following three-level approach:
|
||||||
|
|
||||||
* Create a ``base.html`` template that holds the main look-and-feel of your
|
* Create a ``base.html`` template that holds the main look-and-feel of your
|
||||||
site.
|
site.
|
||||||
* Create a ``base_SECTIONNAME.html`` template for each "section" of your
|
* Create a ``base_SECTIONNAME.html`` template for each "section" of your
|
||||||
site. For example, ``base_news.html``, ``base_sports.html``. These
|
site. For example, ``base_news.html``, ``base_sports.html``. These
|
||||||
templates all extend ``base.html`` and include section-specific
|
templates all extend ``base.html`` and include section-specific
|
||||||
styles/design.
|
styles/design.
|
||||||
* Create individual templates for each type of page, such as a news
|
* Create individual templates for each type of page, such as a news
|
||||||
article or blog entry. These templates extend the appropriate section
|
article or blog entry. These templates extend the appropriate section
|
||||||
template.
|
template.
|
||||||
|
|
||||||
This approach maximizes code reuse and makes it easy to add items to shared
|
This approach maximizes code reuse and makes it easy to add items to shared
|
||||||
content areas, such as section-wide navigation.
|
content areas, such as section-wide navigation.
|
||||||
|
|
||||||
Here are some tips for working with inheritance:
|
Here are some tips for working with inheritance:
|
||||||
|
|
||||||
* If you use :ttag:`{% extends %}<extends>` in a template, it must be the first template
|
* If you use :ttag:`{% extends %}<extends>` in a template, it must be the first template
|
||||||
tag in that template. Template inheritance won't work, otherwise.
|
tag in that template. Template inheritance won't work, otherwise.
|
||||||
|
|
||||||
* More :ttag:`{% block %}<block>` tags in your base templates are better. Remember,
|
* More :ttag:`{% block %}<block>` tags in your base templates are better. Remember,
|
||||||
child templates don't have to define all parent blocks, so you can fill
|
child templates don't have to define all parent blocks, so you can fill
|
||||||
in reasonable defaults in a number of blocks, then only define the ones
|
in reasonable defaults in a number of blocks, then only define the ones
|
||||||
you need later. It's better to have more hooks than fewer hooks.
|
you need later. It's better to have more hooks than fewer hooks.
|
||||||
|
|
||||||
* If you find yourself duplicating content in a number of templates, it
|
* If you find yourself duplicating content in a number of templates, it
|
||||||
probably means you should move that content to a ``{% block %}`` in a
|
probably means you should move that content to a ``{% block %}`` in a
|
||||||
parent template.
|
parent template.
|
||||||
|
|
||||||
* If you need to get the content of the block from the parent template,
|
* If you need to get the content of the block from the parent template,
|
||||||
the ``{{ block.super }}`` variable will do the trick. This is useful
|
the ``{{ block.super }}`` variable will do the trick. This is useful
|
||||||
if you want to add to the contents of a parent block instead of
|
if you want to add to the contents of a parent block instead of
|
||||||
completely overriding it. Data inserted using ``{{ block.super }}`` will
|
completely overriding it. Data inserted using ``{{ block.super }}`` will
|
||||||
not be automatically escaped (see the `next section`_), since it was
|
not be automatically escaped (see the `next section`_), since it was
|
||||||
already escaped, if necessary, in the parent template.
|
already escaped, if necessary, in the parent template.
|
||||||
|
|
||||||
* For extra readability, you can optionally give a *name* to your
|
* For extra readability, you can optionally give a *name* to your
|
||||||
``{% endblock %}`` tag. For example::
|
``{% endblock %}`` tag. For example::
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
...
|
...
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
In larger templates, this technique helps you see which ``{% block %}``
|
In larger templates, this technique helps you see which ``{% block %}``
|
||||||
tags are being closed.
|
tags are being closed.
|
||||||
|
|
||||||
Finally, note that you can't define multiple :ttag:`block` tags with the same
|
Finally, note that you can't define multiple :ttag:`block` tags with the same
|
||||||
name in the same template. This limitation exists because a block tag works in
|
name in the same template. This limitation exists because a block tag works in
|
||||||
|
@ -437,25 +437,25 @@ do potentially bad things. This type of security exploit is called a
|
||||||
|
|
||||||
To avoid this problem, you have two options:
|
To avoid this problem, you have two options:
|
||||||
|
|
||||||
* One, you can make sure to run each untrusted variable through the
|
* One, you can make sure to run each untrusted variable through the
|
||||||
:tfilter:`escape` filter (documented below), which converts potentially
|
:tfilter:`escape` filter (documented below), which converts potentially
|
||||||
harmful HTML characters to unharmful ones. This was the default solution
|
harmful HTML characters to unharmful ones. This was the default solution
|
||||||
in Django for its first few years, but the problem is that it puts the
|
in Django for its first few years, but the problem is that it puts the
|
||||||
onus on *you*, the developer / template author, to ensure you're escaping
|
onus on *you*, the developer / template author, to ensure you're escaping
|
||||||
everything. It's easy to forget to escape data.
|
everything. It's easy to forget to escape data.
|
||||||
|
|
||||||
* Two, you can take advantage of Django's automatic HTML escaping. The
|
* Two, you can take advantage of Django's automatic HTML escaping. The
|
||||||
remainder of this section describes how auto-escaping works.
|
remainder of this section describes how auto-escaping works.
|
||||||
|
|
||||||
By default in Django, every template automatically escapes the output
|
By default in Django, every template automatically escapes the output
|
||||||
of every variable tag. Specifically, these five characters are
|
of every variable tag. Specifically, these five characters are
|
||||||
escaped:
|
escaped:
|
||||||
|
|
||||||
* ``<`` is converted to ``<``
|
* ``<`` is converted to ``<``
|
||||||
* ``>`` is converted to ``>``
|
* ``>`` is converted to ``>``
|
||||||
* ``'`` (single quote) is converted to ``'``
|
* ``'`` (single quote) is converted to ``'``
|
||||||
* ``"`` (double quote) is converted to ``"``
|
* ``"`` (double quote) is converted to ``"``
|
||||||
* ``&`` is converted to ``&``
|
* ``&`` is converted to ``&``
|
||||||
|
|
||||||
Again, we stress that this behavior is on by default. If you're using Django's
|
Again, we stress that this behavior is on by default. If you're using Django's
|
||||||
template system, you're protected.
|
template system, you're protected.
|
||||||
|
|
Loading…
Reference in New Issue