Removed unnecessary code-block directives.
This commit is contained in:
parent
fa02120d36
commit
9d6551204e
|
@ -540,9 +540,7 @@ class WizardView(TemplateView):
|
||||||
* all extra data stored in the storage backend
|
* all extra data stored in the storage backend
|
||||||
* `wizard` - a dictionary representation of the wizard instance
|
* `wizard` - a dictionary representation of the wizard instance
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class MyWizard(WizardView):
|
class MyWizard(WizardView):
|
||||||
def get_context_data(self, form, **kwargs):
|
def get_context_data(self, form, **kwargs):
|
||||||
|
|
|
@ -46,9 +46,7 @@ The ``closepoll.py`` module has only one requirement -- it must define a class
|
||||||
or from Windows scheduled tasks control panel.
|
or from Windows scheduled tasks control panel.
|
||||||
|
|
||||||
To implement the command, edit ``polls/management/commands/closepoll.py`` to
|
To implement the command, edit ``polls/management/commands/closepoll.py`` to
|
||||||
look like this:
|
look like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from polls.models import Poll
|
from polls.models import Poll
|
||||||
|
@ -108,9 +106,7 @@ Accepting optional arguments
|
||||||
|
|
||||||
The same ``closepoll`` could be easily modified to delete a given poll instead
|
The same ``closepoll`` could be easily modified to delete a given poll instead
|
||||||
of closing it by accepting additional command line options. These custom
|
of closing it by accepting additional command line options. These custom
|
||||||
options can be added in the :meth:`~BaseCommand.add_arguments` method like this:
|
options can be added in the :meth:`~BaseCommand.add_arguments` method like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
@ -157,9 +153,7 @@ require a system-neutral string language (for which we use 'en-us').
|
||||||
If, for some reason, your custom management command needs to use a fixed locale
|
If, for some reason, your custom management command needs to use a fixed locale
|
||||||
different from 'en-us', you should manually activate and deactivate it in your
|
different from 'en-us', you should manually activate and deactivate it in your
|
||||||
:meth:`~BaseCommand.handle` method using the functions provided by the I18N
|
:meth:`~BaseCommand.handle` method using the functions provided by the I18N
|
||||||
support code:
|
support code::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
@ -174,12 +168,11 @@ support code:
|
||||||
translation.activate('ru')
|
translation.activate('ru')
|
||||||
|
|
||||||
# Or you can activate the LANGUAGE_CODE # chosen in the settings:
|
# Or you can activate the LANGUAGE_CODE # chosen in the settings:
|
||||||
#
|
from django.conf import settings
|
||||||
#from django.conf import settings
|
translation.activate(settings.LANGUAGE_CODE)
|
||||||
#translation.activate(settings.LANGUAGE_CODE)
|
|
||||||
|
|
||||||
# Your command logic here
|
# Your command logic here
|
||||||
# ...
|
...
|
||||||
|
|
||||||
translation.deactivate()
|
translation.deactivate()
|
||||||
|
|
||||||
|
@ -323,15 +316,13 @@ the :meth:`~BaseCommand.handle` method must be implemented.
|
||||||
|
|
||||||
.. admonition:: Implementing a constructor in a subclass
|
.. admonition:: Implementing a constructor in a subclass
|
||||||
|
|
||||||
If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
|
If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
|
||||||
you must call :class:`BaseCommand`’s ``__init__``.
|
you must call :class:`BaseCommand`’s ``__init__``::
|
||||||
|
|
||||||
.. code-block:: python
|
class Command(BaseCommand):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
class Command(BaseCommand):
|
super(Command, self).__init__(*args, **kwargs)
|
||||||
def __init__(self, *args, **kwargs):
|
# ...
|
||||||
super(Command, self).__init__(*args, **kwargs)
|
|
||||||
# ...
|
|
||||||
|
|
||||||
.. method:: BaseCommand.add_arguments(parser)
|
.. method:: BaseCommand.add_arguments(parser)
|
||||||
|
|
||||||
|
|
|
@ -57,15 +57,12 @@ tags/filters for the given Python module name, not the name of the app.
|
||||||
To be a valid tag library, the module must contain a module-level variable
|
To be a valid tag library, the module must contain a module-level variable
|
||||||
named ``register`` that is a ``template.Library`` instance, in which all the
|
named ``register`` that is a ``template.Library`` instance, in which all the
|
||||||
tags and filters are registered. So, near the top of your module, put the
|
tags and filters are registered. So, near the top of your module, put the
|
||||||
following:
|
following::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
.. admonition:: Behind the scenes
|
.. admonition:: Behind the scenes
|
||||||
|
|
||||||
For a ton of examples, read the source code for Django's default filters
|
For a ton of examples, read the source code for Django's default filters
|
||||||
|
@ -94,9 +91,7 @@ reasonable fallback value to return. In case of input that represents a clear
|
||||||
bug in a template, raising an exception may still be better than silent failure
|
bug in a template, raising an exception may still be better than silent failure
|
||||||
which hides the bug.
|
which hides the bug.
|
||||||
|
|
||||||
Here's an example filter definition:
|
Here's an example filter definition::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def cut(value, arg):
|
def cut(value, arg):
|
||||||
"""Removes all values of arg from the given string"""
|
"""Removes all values of arg from the given string"""
|
||||||
|
@ -109,9 +104,7 @@ And here's an example of how that filter would be used:
|
||||||
{{ somevariable|cut:"0" }}
|
{{ somevariable|cut:"0" }}
|
||||||
|
|
||||||
Most filters don't take arguments. In this case, just leave the argument out of
|
Most filters don't take arguments. In this case, just leave the argument out of
|
||||||
your function. Example:
|
your function. Example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def lower(value): # Only one argument.
|
def lower(value): # Only one argument.
|
||||||
"""Converts a string into all lowercase"""
|
"""Converts a string into all lowercase"""
|
||||||
|
@ -123,9 +116,7 @@ Registering custom filters
|
||||||
.. method:: django.template.Library.filter()
|
.. method:: django.template.Library.filter()
|
||||||
|
|
||||||
Once you've written your filter definition, you need to register it with
|
Once you've written your filter definition, you need to register it with
|
||||||
your ``Library`` instance, to make it available to Django's template language:
|
your ``Library`` instance, to make it available to Django's template language::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
register.filter('cut', cut)
|
register.filter('cut', cut)
|
||||||
register.filter('lower', lower)
|
register.filter('lower', lower)
|
||||||
|
@ -136,9 +127,7 @@ The ``Library.filter()`` method takes two arguments:
|
||||||
2. The compilation function -- a Python function (not the name of the
|
2. The compilation function -- a Python function (not the name of the
|
||||||
function as a string).
|
function as a string).
|
||||||
|
|
||||||
You can use ``register.filter()`` as a decorator instead:
|
You can use ``register.filter()`` as a decorator instead::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.filter(name='cut')
|
@register.filter(name='cut')
|
||||||
def cut(value, arg):
|
def cut(value, arg):
|
||||||
|
@ -163,9 +152,7 @@ Template filters that expect strings
|
||||||
|
|
||||||
If you're writing a template filter that only expects a string as the first
|
If you're writing a template filter that only expects a string as the first
|
||||||
argument, you should use the decorator ``stringfilter``. This will
|
argument, you should use the decorator ``stringfilter``. This will
|
||||||
convert an object to its string value before being passed to your function:
|
convert an object to its string value before being passed to your function::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.template.defaultfilters import stringfilter
|
from django.template.defaultfilters import stringfilter
|
||||||
|
@ -201,9 +188,7 @@ passed around inside the template code:
|
||||||
|
|
||||||
Internally, these strings are of type ``SafeBytes`` or ``SafeText``.
|
Internally, these strings are of type ``SafeBytes`` or ``SafeText``.
|
||||||
They share a common base class of ``SafeData``, so you can test
|
They share a common base class of ``SafeData``, so you can test
|
||||||
for them using code like:
|
for them using code like::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
if isinstance(value, SafeData):
|
if isinstance(value, SafeData):
|
||||||
# Do something with the "safe" string.
|
# Do something with the "safe" string.
|
||||||
|
@ -224,9 +209,7 @@ Template filter code falls into one of two situations:
|
||||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||||
this case, you can let Django take care of all the auto-escaping
|
this case, you can let Django take care of all the auto-escaping
|
||||||
handling for you. All you need to do is set the ``is_safe`` flag to ``True``
|
handling for you. All you need to do is set the ``is_safe`` flag to ``True``
|
||||||
when you register your filter function, like so:
|
when you register your filter function, like so::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def myfilter(value):
|
def myfilter(value):
|
||||||
|
@ -248,9 +231,7 @@ Template filter code falls into one of two situations:
|
||||||
For example, suppose you have a filter that adds the string ``xx`` to
|
For example, suppose you have a filter that adds the string ``xx`` to
|
||||||
the end of any input. Since this introduces no dangerous HTML characters
|
the end of any input. Since this introduces no dangerous HTML characters
|
||||||
to the result (aside from any that were already present), you should
|
to the result (aside from any that were already present), you should
|
||||||
mark your filter with ``is_safe``:
|
mark your filter with ``is_safe``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def add_xx(value):
|
def add_xx(value):
|
||||||
|
@ -302,9 +283,7 @@ Template filter code falls into one of two situations:
|
||||||
effect and ``False`` otherwise.
|
effect and ``False`` otherwise.
|
||||||
|
|
||||||
For example, let's write a filter that emphasizes the first character of
|
For example, let's write a filter that emphasizes the first character of
|
||||||
a string:
|
a string::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.utils.html import conditional_escape
|
from django.utils.html import conditional_escape
|
||||||
|
@ -376,9 +355,7 @@ Filters and time zones
|
||||||
|
|
||||||
If you write a custom filter that operates on :class:`~datetime.datetime`
|
If you write a custom filter that operates on :class:`~datetime.datetime`
|
||||||
objects, you'll usually register it with the ``expects_localtime`` flag set to
|
objects, you'll usually register it with the ``expects_localtime`` flag set to
|
||||||
``True``:
|
``True``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.filter(expects_localtime=True)
|
@register.filter(expects_localtime=True)
|
||||||
def businesshours(value):
|
def businesshours(value):
|
||||||
|
@ -432,11 +409,10 @@ anything else. In our case, let's say the tag should be used like this:
|
||||||
<p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
|
<p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
|
||||||
|
|
||||||
The parser for this function should grab the parameter and create a ``Node``
|
The parser for this function should grab the parameter and create a ``Node``
|
||||||
object:
|
object::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
|
|
||||||
def do_current_time(parser, token):
|
def do_current_time(parser, token):
|
||||||
try:
|
try:
|
||||||
# split_contents() knows not to split quoted strings.
|
# split_contents() knows not to split quoted strings.
|
||||||
|
@ -487,9 +463,7 @@ Writing the renderer
|
||||||
The second step in writing custom tags is to define a ``Node`` subclass that
|
The second step in writing custom tags is to define a ``Node`` subclass that
|
||||||
has a ``render()`` method.
|
has a ``render()`` method.
|
||||||
|
|
||||||
Continuing the above example, we need to define ``CurrentTimeNode``:
|
Continuing the above example, we need to define ``CurrentTimeNode``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from django import template
|
from django import template
|
||||||
|
@ -497,6 +471,7 @@ Continuing the above example, we need to define ``CurrentTimeNode``:
|
||||||
class CurrentTimeNode(template.Node):
|
class CurrentTimeNode(template.Node):
|
||||||
def __init__(self, format_string):
|
def __init__(self, format_string):
|
||||||
self.format_string = format_string
|
self.format_string = format_string
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
return datetime.datetime.now().strftime(self.format_string)
|
return datetime.datetime.now().strftime(self.format_string)
|
||||||
|
|
||||||
|
@ -536,9 +511,7 @@ as such.
|
||||||
Also, if your template tag creates a new context for performing some
|
Also, if your template tag creates a new context for performing some
|
||||||
sub-rendering, set the auto-escape attribute to the current context's value.
|
sub-rendering, set the auto-escape attribute to the current context's value.
|
||||||
The ``__init__`` method for the ``Context`` class takes a parameter called
|
The ``__init__`` method for the ``Context`` class takes a parameter called
|
||||||
``autoescape`` that you can use for this purpose. For example:
|
``autoescape`` that you can use for this purpose. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.template import Context
|
from django.template import Context
|
||||||
|
|
||||||
|
@ -548,9 +521,7 @@ The ``__init__`` method for the ``Context`` class takes a parameter called
|
||||||
# ... Do something with new_context ...
|
# ... Do something with new_context ...
|
||||||
|
|
||||||
This is not a very common situation, but it's useful if you're rendering a
|
This is not a very common situation, but it's useful if you're rendering a
|
||||||
template yourself. For example:
|
template yourself. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
t = template.loader.get_template('small_fragment.html')
|
t = template.loader.get_template('small_fragment.html')
|
||||||
|
@ -585,9 +556,7 @@ it's rendered:
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
A naive implementation of ``CycleNode`` might look something like this:
|
A naive implementation of ``CycleNode`` might look something like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
from django import template
|
from django import template
|
||||||
|
@ -595,6 +564,7 @@ A naive implementation of ``CycleNode`` might look something like this:
|
||||||
class CycleNode(template.Node):
|
class CycleNode(template.Node):
|
||||||
def __init__(self, cyclevars):
|
def __init__(self, cyclevars):
|
||||||
self.cycle_iter = itertools.cycle(cyclevars)
|
self.cycle_iter = itertools.cycle(cyclevars)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
return next(self.cycle_iter)
|
return next(self.cycle_iter)
|
||||||
|
|
||||||
|
@ -619,13 +589,12 @@ with the ``context`` of the template that is currently being rendered. The
|
||||||
``render_context`` behaves like a Python dictionary, and should be used to
|
``render_context`` behaves like a Python dictionary, and should be used to
|
||||||
store ``Node`` state between invocations of the ``render`` method.
|
store ``Node`` state between invocations of the ``render`` method.
|
||||||
|
|
||||||
Let's refactor our ``CycleNode`` implementation to use the ``render_context``:
|
Let's refactor our ``CycleNode`` implementation to use the ``render_context``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class CycleNode(template.Node):
|
class CycleNode(template.Node):
|
||||||
def __init__(self, cyclevars):
|
def __init__(self, cyclevars):
|
||||||
self.cyclevars = cyclevars
|
self.cyclevars = cyclevars
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
if self not in context.render_context:
|
if self not in context.render_context:
|
||||||
context.render_context[self] = itertools.cycle(self.cyclevars)
|
context.render_context[self] = itertools.cycle(self.cyclevars)
|
||||||
|
@ -652,9 +621,7 @@ Registering the tag
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Finally, register the tag with your module's ``Library`` instance, as explained
|
Finally, register the tag with your module's ``Library`` instance, as explained
|
||||||
in "Writing custom template filters" above. Example:
|
in "Writing custom template filters" above. Example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
register.tag('current_time', do_current_time)
|
register.tag('current_time', do_current_time)
|
||||||
|
|
||||||
|
@ -665,9 +632,7 @@ The ``tag()`` method takes two arguments:
|
||||||
2. The compilation function -- a Python function (not the name of the
|
2. The compilation function -- a Python function (not the name of the
|
||||||
function as a string).
|
function as a string).
|
||||||
|
|
||||||
As with filter registration, it is also possible to use this as a decorator:
|
As with filter registration, it is also possible to use this as a decorator::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.tag(name="current_time")
|
@register.tag(name="current_time")
|
||||||
def do_current_time(parser, token):
|
def do_current_time(parser, token):
|
||||||
|
@ -706,9 +671,7 @@ Initially, ``token.split_contents()`` will return three values:
|
||||||
``split_contents()`` will include the leading and trailing quotes for
|
``split_contents()`` will include the leading and trailing quotes for
|
||||||
string literals like this.
|
string literals like this.
|
||||||
|
|
||||||
Now your tag should begin to look like this:
|
Now your tag should begin to look like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
|
|
||||||
|
@ -728,9 +691,7 @@ accomplished by using the ``Variable()`` class in ``django.template``.
|
||||||
|
|
||||||
To use the ``Variable`` class, simply instantiate it with the name of the
|
To use the ``Variable`` class, simply instantiate it with the name of the
|
||||||
variable to be resolved, and then call ``variable.resolve(context)``. So,
|
variable to be resolved, and then call ``variable.resolve(context)``. So,
|
||||||
for example:
|
for example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class FormatTimeNode(template.Node):
|
class FormatTimeNode(template.Node):
|
||||||
def __init__(self, date_to_be_formatted, format_string):
|
def __init__(self, date_to_be_formatted, format_string):
|
||||||
|
@ -766,9 +727,7 @@ To ease the creation of these types of tags, Django provides a helper function,
|
||||||
arguments, wraps it in a ``render`` function and the other necessary bits
|
arguments, wraps it in a ``render`` function and the other necessary bits
|
||||||
mentioned above and registers it with the template system.
|
mentioned above and registers it with the template system.
|
||||||
|
|
||||||
Our earlier ``current_time`` function could thus be written like this:
|
Our earlier ``current_time`` function could thus be written like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from django import template
|
from django import template
|
||||||
|
@ -780,9 +739,7 @@ Our earlier ``current_time`` function could thus be written like this:
|
||||||
|
|
||||||
register.simple_tag(current_time)
|
register.simple_tag(current_time)
|
||||||
|
|
||||||
The decorator syntax also works:
|
The decorator syntax also works::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def current_time(format_string):
|
def current_time(format_string):
|
||||||
|
@ -798,9 +755,7 @@ A few things to note about the ``simple_tag`` helper function:
|
||||||
current value of the variable, not the variable itself.
|
current value of the variable, not the variable itself.
|
||||||
|
|
||||||
If your template tag needs to access the current context, you can use the
|
If your template tag needs to access the current context, you can use the
|
||||||
``takes_context`` argument when registering your tag:
|
``takes_context`` argument when registering your tag::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# The first argument *must* be called "context" here.
|
# The first argument *must* be called "context" here.
|
||||||
def current_time(context, format_string):
|
def current_time(context, format_string):
|
||||||
|
@ -809,9 +764,7 @@ If your template tag needs to access the current context, you can use the
|
||||||
|
|
||||||
register.simple_tag(takes_context=True)(current_time)
|
register.simple_tag(takes_context=True)(current_time)
|
||||||
|
|
||||||
Or, using decorator syntax:
|
Or, using decorator syntax::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
def current_time(context, format_string):
|
def current_time(context, format_string):
|
||||||
|
@ -821,9 +774,7 @@ Or, using decorator syntax:
|
||||||
For more information on how the ``takes_context`` option works, see the section
|
For more information on how the ``takes_context`` option works, see the section
|
||||||
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
|
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
|
||||||
|
|
||||||
If you need to rename your tag, you can provide a custom name for it:
|
If you need to rename your tag, you can provide a custom name for it::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
register.simple_tag(lambda x: x - 1, name='minusone')
|
register.simple_tag(lambda x: x - 1, name='minusone')
|
||||||
|
|
||||||
|
@ -832,9 +783,7 @@ If you need to rename your tag, you can provide a custom name for it:
|
||||||
return value - 2
|
return value - 2
|
||||||
|
|
||||||
``simple_tag`` functions may accept any number of positional or keyword
|
``simple_tag`` functions may accept any number of positional or keyword
|
||||||
arguments. For example:
|
arguments. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
@ -888,9 +837,7 @@ created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:
|
||||||
First, define the function that takes the argument and produces a dictionary of
|
First, define the function that takes the argument and produces a dictionary of
|
||||||
data for the result. The important point here is we only need to return a
|
data for the result. The important point here is we only need to return a
|
||||||
dictionary, not anything more complex. This will be used as a template context
|
dictionary, not anything more complex. This will be used as a template context
|
||||||
for the template fragment. Example:
|
for the template fragment. Example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def show_results(poll):
|
def show_results(poll):
|
||||||
choices = poll.choice_set.all()
|
choices = poll.choice_set.all()
|
||||||
|
@ -911,25 +858,19 @@ designer. Following our example, the template is very simple:
|
||||||
Now, create and register the inclusion tag by calling the ``inclusion_tag()``
|
Now, create and register the inclusion tag by calling the ``inclusion_tag()``
|
||||||
method on a ``Library`` object. Following our example, if the above template is
|
method on a ``Library`` object. Following our example, if the above template is
|
||||||
in a file called ``results.html`` in a directory that's searched by the
|
in a file called ``results.html`` in a directory that's searched by the
|
||||||
template loader, we'd register the tag like this:
|
template loader, we'd register the tag like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# Here, register is a django.template.Library instance, as before
|
# Here, register is a django.template.Library instance, as before
|
||||||
register.inclusion_tag('results.html')(show_results)
|
register.inclusion_tag('results.html')(show_results)
|
||||||
|
|
||||||
Alternatively it is possible to register the inclusion tag using a
|
Alternatively it is possible to register the inclusion tag using a
|
||||||
:class:`django.template.Template` instance:
|
:class:`django.template.Template` instance::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
t = get_template('results.html')
|
t = get_template('results.html')
|
||||||
register.inclusion_tag(t)(show_results)
|
register.inclusion_tag(t)(show_results)
|
||||||
|
|
||||||
As always, decorator syntax works as well, so we could have written:
|
As always, decorator syntax works as well, so we could have written::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.inclusion_tag('results.html')
|
@register.inclusion_tag('results.html')
|
||||||
def show_results(poll):
|
def show_results(poll):
|
||||||
|
@ -946,9 +887,7 @@ will have one argument -- the template context as of when the tag was called.
|
||||||
|
|
||||||
For example, say you're writing an inclusion tag that will always be used in a
|
For example, say you're writing an inclusion tag that will always be used in a
|
||||||
context that contains ``home_link`` and ``home_title`` variables that point
|
context that contains ``home_link`` and ``home_title`` variables that point
|
||||||
back to the main page. Here's what the Python function would look like:
|
back to the main page. Here's what the Python function would look like::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# The first argument *must* be called "context" here.
|
# The first argument *must* be called "context" here.
|
||||||
def jump_link(context):
|
def jump_link(context):
|
||||||
|
@ -984,9 +923,7 @@ The ``takes_context`` parameter defaults to ``False``. When it's set to
|
||||||
only difference between this case and the previous ``inclusion_tag`` example.
|
only difference between this case and the previous ``inclusion_tag`` example.
|
||||||
|
|
||||||
``inclusion_tag`` functions may accept any number of positional or keyword
|
``inclusion_tag`` functions may accept any number of positional or keyword
|
||||||
arguments. For example:
|
arguments. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.inclusion_tag('my_template.html')
|
@register.inclusion_tag('my_template.html')
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
@ -1014,9 +951,7 @@ template authors can reuse the values that your template tags create.
|
||||||
To set a variable in the context, just use dictionary assignment on the context
|
To set a variable in the context, just use dictionary assignment on the context
|
||||||
object in the ``render()`` method. Here's an updated version of
|
object in the ``render()`` method. Here's an updated version of
|
||||||
``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
|
``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
|
||||||
outputting it:
|
outputting it::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from django import template
|
from django import template
|
||||||
|
@ -1058,9 +993,9 @@ like so:
|
||||||
<p>The current time is {{ my_current_time }}.</p>
|
<p>The current time is {{ my_current_time }}.</p>
|
||||||
|
|
||||||
To do that, you'll need to refactor both the compilation function and ``Node``
|
To do that, you'll need to refactor both the compilation function and ``Node``
|
||||||
class, like so:
|
class, like so::
|
||||||
|
|
||||||
.. code-block:: python
|
import re
|
||||||
|
|
||||||
class CurrentTimeNode3(template.Node):
|
class CurrentTimeNode3(template.Node):
|
||||||
def __init__(self, format_string, var_name):
|
def __init__(self, format_string, var_name):
|
||||||
|
@ -1070,7 +1005,6 @@ class, like so:
|
||||||
context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
|
context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
import re
|
|
||||||
def do_current_time(parser, token):
|
def do_current_time(parser, token):
|
||||||
# This version uses a regular expression to parse tag contents.
|
# This version uses a regular expression to parse tag contents.
|
||||||
try:
|
try:
|
||||||
|
@ -1104,18 +1038,14 @@ a helper function, ``assignment_tag``. This function works the same way as
|
||||||
stores the tag's result in a specified context variable instead of directly
|
stores the tag's result in a specified context variable instead of directly
|
||||||
outputting it.
|
outputting it.
|
||||||
|
|
||||||
Our earlier ``current_time`` function could thus be written like this:
|
Our earlier ``current_time`` function could thus be written like this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def get_current_time(format_string):
|
def get_current_time(format_string):
|
||||||
return datetime.datetime.now().strftime(format_string)
|
return datetime.datetime.now().strftime(format_string)
|
||||||
|
|
||||||
register.assignment_tag(get_current_time)
|
register.assignment_tag(get_current_time)
|
||||||
|
|
||||||
The decorator syntax also works:
|
The decorator syntax also works::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.assignment_tag
|
@register.assignment_tag
|
||||||
def get_current_time(format_string):
|
def get_current_time(format_string):
|
||||||
|
@ -1130,9 +1060,7 @@ followed by the variable name, and output it yourself where you see fit:
|
||||||
<p>The time is {{ the_time }}.</p>
|
<p>The time is {{ the_time }}.</p>
|
||||||
|
|
||||||
If your template tag needs to access the current context, you can use the
|
If your template tag needs to access the current context, you can use the
|
||||||
``takes_context`` argument when registering your tag:
|
``takes_context`` argument when registering your tag::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# The first argument *must* be called "context" here.
|
# The first argument *must* be called "context" here.
|
||||||
def get_current_time(context, format_string):
|
def get_current_time(context, format_string):
|
||||||
|
@ -1141,9 +1069,7 @@ If your template tag needs to access the current context, you can use the
|
||||||
|
|
||||||
register.assignment_tag(takes_context=True)(get_current_time)
|
register.assignment_tag(takes_context=True)(get_current_time)
|
||||||
|
|
||||||
Or, using decorator syntax:
|
Or, using decorator syntax::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.assignment_tag(takes_context=True)
|
@register.assignment_tag(takes_context=True)
|
||||||
def get_current_time(context, format_string):
|
def get_current_time(context, format_string):
|
||||||
|
@ -1154,9 +1080,7 @@ For more information on how the ``takes_context`` option works, see the section
|
||||||
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
|
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
|
||||||
|
|
||||||
``assignment_tag`` functions may accept any number of positional or keyword
|
``assignment_tag`` functions may accept any number of positional or keyword
|
||||||
arguments. For example:
|
arguments. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.assignment_tag
|
@register.assignment_tag
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
@ -1182,9 +1106,7 @@ Template tags can work in tandem. For instance, the standard
|
||||||
To create a template tag such as this, use ``parser.parse()`` in your
|
To create a template tag such as this, use ``parser.parse()`` in your
|
||||||
compilation function.
|
compilation function.
|
||||||
|
|
||||||
Here's how a simplified ``{% comment %}`` tag might be implemented:
|
Here's how a simplified ``{% comment %}`` tag might be implemented::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def do_comment(parser, token):
|
def do_comment(parser, token):
|
||||||
nodelist = parser.parse(('endcomment',))
|
nodelist = parser.parse(('endcomment',))
|
||||||
|
@ -1237,9 +1159,7 @@ Usage:
|
||||||
{% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
|
{% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
|
||||||
|
|
||||||
As in the previous example, we'll use ``parser.parse()``. But this time, we
|
As in the previous example, we'll use ``parser.parse()``. But this time, we
|
||||||
pass the resulting ``nodelist`` to the ``Node``:
|
pass the resulting ``nodelist`` to the ``Node``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def do_upper(parser, token):
|
def do_upper(parser, token):
|
||||||
nodelist = parser.parse(('endupper',))
|
nodelist = parser.parse(('endupper',))
|
||||||
|
|
|
@ -352,9 +352,7 @@ In your Web root directory, add this to a file named ``.htaccess``:
|
||||||
|
|
||||||
Then, create a small script that tells Apache how to spawn your FastCGI
|
Then, create a small script that tells Apache how to spawn your FastCGI
|
||||||
program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
|
program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
|
||||||
be sure to make it executable:
|
be sure to make it executable::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
|
@ -72,9 +72,7 @@ application :doc:`that is created by django-admin startproject
|
||||||
|
|
||||||
Finally, edit your WSGI script ``mysite.wsgi`` to tie Apache's authentication
|
Finally, edit your WSGI script ``mysite.wsgi`` to tie Apache's authentication
|
||||||
to your site's authentication mechanisms by importing the ``check_password``
|
to your site's authentication mechanisms by importing the ``check_password``
|
||||||
function:
|
function::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
|
@ -600,10 +600,12 @@ the Python import path to your :file:`mysite/settings.py` file.
|
||||||
|
|
||||||
If you'd rather not use :file:`manage.py`, no problem. Just set the
|
If you'd rather not use :file:`manage.py`, no problem. Just set the
|
||||||
:envvar:`DJANGO_SETTINGS_MODULE` environment variable to
|
:envvar:`DJANGO_SETTINGS_MODULE` environment variable to
|
||||||
``mysite.settings``, start a plain Python shell, and set up Django::
|
``mysite.settings``, start a plain Python shell, and set up Django:
|
||||||
|
|
||||||
>>> import django
|
.. code-block:: pycon
|
||||||
>>> django.setup()
|
|
||||||
|
>>> import django
|
||||||
|
>>> django.setup()
|
||||||
|
|
||||||
If this raises an :exc:`AttributeError`, you're probably using
|
If this raises an :exc:`AttributeError`, you're probably using
|
||||||
a version of Django that doesn't match this tutorial version. You'll want
|
a version of Django that doesn't match this tutorial version. You'll want
|
||||||
|
|
|
@ -2567,9 +2567,7 @@ Adding a password-reset feature
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
You can add a password-reset feature to the admin site by adding a few lines to
|
You can add a password-reset feature to the admin site by adding a few lines to
|
||||||
your URLconf. Specifically, add these four patterns:
|
your URLconf. Specifically, add these four patterns::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
|
|
||||||
|
|
|
@ -149,9 +149,7 @@ If using a binary package of GEOS (e.g., on Ubuntu), you may need to :ref:`binut
|
||||||
If your GEOS library is in a non-standard location, or you don't want to
|
If your GEOS library is in a non-standard location, or you don't want to
|
||||||
modify the system's library path then the :setting:`GEOS_LIBRARY_PATH`
|
modify the system's library path then the :setting:`GEOS_LIBRARY_PATH`
|
||||||
setting may be added to your Django settings file with the full path to the
|
setting may be added to your Django settings file with the full path to the
|
||||||
GEOS C library. For example:
|
GEOS C library. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
GEOS_LIBRARY_PATH = '/home/bob/local/lib/libgeos_c.so'
|
GEOS_LIBRARY_PATH = '/home/bob/local/lib/libgeos_c.so'
|
||||||
|
|
||||||
|
@ -237,7 +235,7 @@ Can't find GDAL library
|
||||||
When GeoDjango can't find the GDAL library, the ``HAS_GDAL`` flag
|
When GeoDjango can't find the GDAL library, the ``HAS_GDAL`` flag
|
||||||
will be false:
|
will be false:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: pycon
|
||||||
|
|
||||||
>>> from django.contrib.gis import gdal
|
>>> from django.contrib.gis import gdal
|
||||||
>>> gdal.HAS_GDAL
|
>>> gdal.HAS_GDAL
|
||||||
|
@ -254,9 +252,7 @@ The solution is to properly configure your :ref:`libsettings` *or* set
|
||||||
If your GDAL library is in a non-standard location, or you don't want to
|
If your GDAL library is in a non-standard location, or you don't want to
|
||||||
modify the system's library path then the :setting:`GDAL_LIBRARY_PATH`
|
modify the system's library path then the :setting:`GDAL_LIBRARY_PATH`
|
||||||
setting may be added to your Django settings file with the full path to
|
setting may be added to your Django settings file with the full path to
|
||||||
the GDAL library. For example:
|
the GDAL library. For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
GDAL_LIBRARY_PATH = '/home/sue/local/lib/libgdal.so'
|
GDAL_LIBRARY_PATH = '/home/sue/local/lib/libgdal.so'
|
||||||
|
|
||||||
|
|
|
@ -180,9 +180,7 @@ location available in your ``PATH``. For example::
|
||||||
$ sudo cp spatialite /Library/Frameworks/SQLite3.framework/Programs
|
$ sudo cp spatialite /Library/Frameworks/SQLite3.framework/Programs
|
||||||
|
|
||||||
Finally, for GeoDjango to be able to find the KyngChaos SpatiaLite library,
|
Finally, for GeoDjango to be able to find the KyngChaos SpatiaLite library,
|
||||||
add the following to your ``settings.py``:
|
add the following to your ``settings.py``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
SPATIALITE_LIBRARY_PATH='/Library/Frameworks/SQLite3.framework/SQLite3'
|
SPATIALITE_LIBRARY_PATH='/Library/Frameworks/SQLite3.framework/SQLite3'
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ foundation for custom widgets.
|
||||||
A dictionary containing HTML attributes to be set on the rendered
|
A dictionary containing HTML attributes to be set on the rendered
|
||||||
widget.
|
widget.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: pycon
|
||||||
|
|
||||||
>>> from django import forms
|
>>> from django import forms
|
||||||
>>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
|
>>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
|
||||||
|
@ -772,9 +772,7 @@ Composite widgets
|
||||||
An optional dict of months to use in the "months" select box.
|
An optional dict of months to use in the "months" select box.
|
||||||
|
|
||||||
The keys of the dict correspond to the month number (1-indexed) and
|
The keys of the dict correspond to the month number (1-indexed) and
|
||||||
the values are the displayed months.
|
the values are the displayed months::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MONTHS = {
|
MONTHS = {
|
||||||
1:_('jan'), 2:_('feb'), 3:_('mar'), 4:_('apr'),
|
1:_('jan'), 2:_('feb'), 3:_('mar'), 4:_('apr'),
|
||||||
|
|
|
@ -432,9 +432,7 @@ Atom1Feed
|
||||||
|
|
||||||
Consider a typical case, where a view might need to call a model's method
|
Consider a typical case, where a view might need to call a model's method
|
||||||
to perform some computation, before placing the model instance into the
|
to perform some computation, before placing the model instance into the
|
||||||
context, where the template might invoke the method once more:
|
context, where the template might invoke the method once more::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# the model
|
# the model
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
|
@ -446,8 +444,12 @@ Atom1Feed
|
||||||
|
|
||||||
# in the view:
|
# in the view:
|
||||||
if person.friends():
|
if person.friends():
|
||||||
|
...
|
||||||
|
|
||||||
|
And in the template you would have:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
# in the template:
|
|
||||||
{% for friend in person.friends %}
|
{% for friend in person.friends %}
|
||||||
|
|
||||||
Here, ``friends()`` will be called twice. Since the instance ``person`` in
|
Here, ``friends()`` will be called twice. Since the instance ``person`` in
|
||||||
|
@ -467,6 +469,7 @@ Atom1Feed
|
||||||
|
|
||||||
# in the view:
|
# in the view:
|
||||||
if person.friends:
|
if person.friends:
|
||||||
|
...
|
||||||
|
|
||||||
The cached value can be treated like an ordinary attribute of the instance::
|
The cached value can be treated like an ordinary attribute of the instance::
|
||||||
|
|
||||||
|
@ -573,18 +576,14 @@ escaping HTML.
|
||||||
because it applies escaping to all arguments - just like the Template system
|
because it applies escaping to all arguments - just like the Template system
|
||||||
applies escaping by default.
|
applies escaping by default.
|
||||||
|
|
||||||
So, instead of writing:
|
So, instead of writing::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
mark_safe("%s <b>%s</b> %s" % (some_html,
|
mark_safe("%s <b>%s</b> %s" % (some_html,
|
||||||
escape(some_text),
|
escape(some_text),
|
||||||
escape(some_other_text),
|
escape(some_other_text),
|
||||||
))
|
))
|
||||||
|
|
||||||
you should instead use:
|
You should instead use::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
format_html("{0} <b>{1}</b> {2}",
|
format_html("{0} <b>{1}</b> {2}",
|
||||||
mark_safe(some_html), some_text, some_other_text)
|
mark_safe(some_html), some_text, some_other_text)
|
||||||
|
|
|
@ -250,9 +250,7 @@ The :ref:`simple_tag<howto-custom-template-tags-simple-tags>`,
|
||||||
newly introduced
|
newly introduced
|
||||||
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
||||||
helper functions may now accept any number of positional or keyword arguments.
|
helper functions may now accept any number of positional or keyword arguments.
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
|
|
@ -288,9 +288,7 @@ The :ref:`simple_tag<howto-custom-template-tags-simple-tags>`,
|
||||||
newly introduced
|
newly introduced
|
||||||
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
||||||
helper functions may now accept any number of positional or keyword arguments.
|
helper functions may now accept any number of positional or keyword arguments.
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
|
|
@ -421,9 +421,7 @@ The :ref:`simple_tag<howto-custom-template-tags-simple-tags>`,
|
||||||
newly introduced
|
newly introduced
|
||||||
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
|
||||||
helper functions may now accept any number of positional or keyword arguments.
|
helper functions may now accept any number of positional or keyword arguments.
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def my_tag(a, b, *args, **kwargs):
|
def my_tag(a, b, *args, **kwargs):
|
||||||
|
|
|
@ -256,9 +256,7 @@ behavior of magic method lookups was changed with Python 2.7 and cursors were
|
||||||
no longer usable as context managers.
|
no longer usable as context managers.
|
||||||
|
|
||||||
Django 1.7 allows a cursor to be used as a context manager that is a shortcut
|
Django 1.7 allows a cursor to be used as a context manager that is a shortcut
|
||||||
for the following, instead of backend specific behavior.
|
for the following, instead of backend specific behavior::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
c = connection.cursor()
|
c = connection.cursor()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -94,7 +94,7 @@ whose username matches the current system user.
|
||||||
You can also change a password programmatically, using
|
You can also change a password programmatically, using
|
||||||
:meth:`~django.contrib.auth.models.User.set_password()`:
|
:meth:`~django.contrib.auth.models.User.set_password()`:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: pycon
|
||||||
|
|
||||||
>>> from django.contrib.auth.models import User
|
>>> from django.contrib.auth.models import User
|
||||||
>>> u = User.objects.get(username='john')
|
>>> u = User.objects.get(username='john')
|
||||||
|
@ -182,9 +182,7 @@ customize permissions for different object instances of the same type.
|
||||||
fields: ``groups`` and ``user_permissions``.
|
fields: ``groups`` and ``user_permissions``.
|
||||||
:class:`~django.contrib.auth.models.User` objects can access their related
|
:class:`~django.contrib.auth.models.User` objects can access their related
|
||||||
objects in the same way as any other :doc:`Django model
|
objects in the same way as any other :doc:`Django model
|
||||||
</topics/db/models>`:
|
</topics/db/models>`::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
myuser.groups = [group_list]
|
myuser.groups = [group_list]
|
||||||
myuser.groups.add(group, group, ...)
|
myuser.groups.add(group, group, ...)
|
||||||
|
|
|
@ -679,7 +679,7 @@ to the ``cache`` template tag; ``vary_on`` is a list of all additional arguments
|
||||||
passed to the tag. This function can be useful for invalidating or overwriting
|
passed to the tag. This function can be useful for invalidating or overwriting
|
||||||
a cached item, for example:
|
a cached item, for example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: pycon
|
||||||
|
|
||||||
>>> from django.core.cache import cache
|
>>> from django.core.cache import cache
|
||||||
>>> from django.core.cache.utils import make_template_fragment_key
|
>>> from django.core.cache.utils import make_template_fragment_key
|
||||||
|
|
|
@ -15,9 +15,11 @@ processing.
|
||||||
Basic Forms
|
Basic Forms
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Given a simple contact form::
|
Given a simple contact form:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: forms.py
|
||||||
|
|
||||||
# forms.py
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
class ContactForm(forms.Form):
|
class ContactForm(forms.Form):
|
||||||
|
@ -28,9 +30,11 @@ Given a simple contact form::
|
||||||
# send email using the self.cleaned_data dictionary
|
# send email using the self.cleaned_data dictionary
|
||||||
pass
|
pass
|
||||||
|
|
||||||
The view can be constructed using a ``FormView``::
|
The view can be constructed using a ``FormView``:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: views.py
|
||||||
|
|
||||||
# views.py
|
|
||||||
from myapp.forms import ContactForm
|
from myapp.forms import ContactForm
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
|
|
||||||
|
@ -91,9 +95,9 @@ add extra validation) simply set
|
||||||
First we need to add :meth:`~django.db.models.Model.get_absolute_url()` to our
|
First we need to add :meth:`~django.db.models.Model.get_absolute_url()` to our
|
||||||
``Author`` class:
|
``Author`` class:
|
||||||
|
|
||||||
.. code-block:: python
|
.. snippet::
|
||||||
|
:filename: models.py
|
||||||
|
|
||||||
# models.py
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -105,9 +109,11 @@ First we need to add :meth:`~django.db.models.Model.get_absolute_url()` to our
|
||||||
|
|
||||||
Then we can use :class:`CreateView` and friends to do the actual
|
Then we can use :class:`CreateView` and friends to do the actual
|
||||||
work. Notice how we're just configuring the generic class-based views
|
work. Notice how we're just configuring the generic class-based views
|
||||||
here; we don't have to write any logic ourselves::
|
here; we don't have to write any logic ourselves:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: views.py
|
||||||
|
|
||||||
# views.py
|
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||||
from django.core.urlresolvers import reverse_lazy
|
from django.core.urlresolvers import reverse_lazy
|
||||||
from myapp.models import Author
|
from myapp.models import Author
|
||||||
|
@ -138,9 +144,11 @@ an :exc:`~django.core.exceptions.ImproperlyConfigured` exception if it's not.
|
||||||
Omitting the ``fields`` attribute was previously allowed and resulted in a
|
Omitting the ``fields`` attribute was previously allowed and resulted in a
|
||||||
form with all of the model's fields.
|
form with all of the model's fields.
|
||||||
|
|
||||||
Finally, we hook these new views into the URLconf::
|
Finally, we hook these new views into the URLconf:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: urls.py
|
||||||
|
|
||||||
# urls.py
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete
|
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete
|
||||||
|
|
||||||
|
@ -177,9 +185,11 @@ Models and request.user
|
||||||
|
|
||||||
To track the user that created an object using a :class:`CreateView`,
|
To track the user that created an object using a :class:`CreateView`,
|
||||||
you can use a custom :class:`~django.forms.ModelForm` to do this. First, add
|
you can use a custom :class:`~django.forms.ModelForm` to do this. First, add
|
||||||
the foreign key relation to the model::
|
the foreign key relation to the model:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: models.py
|
||||||
|
|
||||||
# models.py
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -191,9 +201,11 @@ the foreign key relation to the model::
|
||||||
|
|
||||||
In the view, ensure that you don't include ``created_by`` in the list of fields
|
In the view, ensure that you don't include ``created_by`` in the list of fields
|
||||||
to edit, and override
|
to edit, and override
|
||||||
:meth:`~django.views.generic.edit.ModelFormMixin.form_valid()` to add the user::
|
:meth:`~django.views.generic.edit.ModelFormMixin.form_valid()` to add the user:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: views.py
|
||||||
|
|
||||||
# views.py
|
|
||||||
from django.views.generic.edit import CreateView
|
from django.views.generic.edit import CreateView
|
||||||
from myapp.models import Author
|
from myapp.models import Author
|
||||||
|
|
||||||
|
|
|
@ -222,9 +222,9 @@ we'll want the functionality provided by
|
||||||
We'll demonstrate this with the ``Author`` model we used in the
|
We'll demonstrate this with the ``Author`` model we used in the
|
||||||
:doc:`generic class-based views introduction<generic-display>`.
|
:doc:`generic class-based views introduction<generic-display>`.
|
||||||
|
|
||||||
.. code-block:: python
|
.. snippet::
|
||||||
|
:filename: views.py
|
||||||
|
|
||||||
# views.py
|
|
||||||
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
@ -253,9 +253,11 @@ look up the author we're interested in, which it just does with a simple call
|
||||||
to ``self.get_object()``. Everything else is taken care of for us by the
|
to ``self.get_object()``. Everything else is taken care of for us by the
|
||||||
mixin.
|
mixin.
|
||||||
|
|
||||||
We can hook this into our URLs easily enough::
|
We can hook this into our URLs easily enough:
|
||||||
|
|
||||||
|
.. snippet::
|
||||||
|
:filename: urls.py
|
||||||
|
|
||||||
# urls.py
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from books.views import RecordInterest
|
from books.views import RecordInterest
|
||||||
|
|
||||||
|
@ -519,9 +521,7 @@ The ``AuthorDisplay`` view is almost the same as :ref:`when we
|
||||||
first introduced AuthorDetail<generic-views-extra-work>`; we have to
|
first introduced AuthorDetail<generic-views-extra-work>`; we have to
|
||||||
write our own ``get_context_data()`` to make the
|
write our own ``get_context_data()`` to make the
|
||||||
``AuthorInterestForm`` available to the template. We'll skip the
|
``AuthorInterestForm`` available to the template. We'll skip the
|
||||||
``get_object()`` override from before for clarity.
|
``get_object()`` override from before for clarity::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.views.generic import DetailView
|
from django.views.generic import DetailView
|
||||||
from django import forms
|
from django import forms
|
||||||
|
@ -542,9 +542,7 @@ Then the ``AuthorInterest`` is a simple :class:`FormView`, but we
|
||||||
have to bring in :class:`~django.views.generic.detail.SingleObjectMixin` so we
|
have to bring in :class:`~django.views.generic.detail.SingleObjectMixin` so we
|
||||||
can find the author we're talking about, and we have to remember to set
|
can find the author we're talking about, and we have to remember to set
|
||||||
``template_name`` to ensure that form errors will render the same
|
``template_name`` to ensure that form errors will render the same
|
||||||
template as ``AuthorDisplay`` is using on ``GET``.
|
template as ``AuthorDisplay`` is using on ``GET``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
|
@ -573,9 +571,7 @@ based view, so we can do that at the point we choose between the two subviews.
|
||||||
You can of course pass through keyword arguments to
|
You can of course pass through keyword arguments to
|
||||||
:meth:`~django.views.generic.base.View.as_view()` in the same way you
|
:meth:`~django.views.generic.base.View.as_view()` in the same way you
|
||||||
would in your URLconf, such as if you wanted the ``AuthorInterest`` behavior
|
would in your URLconf, such as if you wanted the ``AuthorInterest`` behavior
|
||||||
to also appear at another URL but using a different template.
|
to also appear at another URL but using a different template::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ collection of objects. This topic guide describes the ways that aggregate values
|
||||||
can be generated and returned using Django queries.
|
can be generated and returned using Django queries.
|
||||||
|
|
||||||
Throughout this guide, we'll refer to the following models. These models are
|
Throughout this guide, we'll refer to the following models. These models are
|
||||||
used to track the inventory for a series of online bookstores:
|
used to track the inventory for a series of online bookstores::
|
||||||
|
|
||||||
.. _queryset-model-example:
|
.. _queryset-model-example:
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,7 @@
|
||||||
Many-to-one relationships
|
Many-to-one relationships
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
.. highlight:: pycon
|
To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`::
|
||||||
|
|
||||||
To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -32,6 +28,8 @@ To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`.
|
||||||
What follows are examples of operations that can be performed using the Python
|
What follows are examples of operations that can be performed using the Python
|
||||||
API facilities.
|
API facilities.
|
||||||
|
|
||||||
|
.. highlight:: pycon
|
||||||
|
|
||||||
Create a few Reporters::
|
Create a few Reporters::
|
||||||
|
|
||||||
>>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
|
>>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
|
||||||
|
|
|
@ -2,13 +2,9 @@
|
||||||
One-to-one relationships
|
One-to-one relationships
|
||||||
########################
|
########################
|
||||||
|
|
||||||
.. highlight:: pycon
|
|
||||||
|
|
||||||
To define a one-to-one relationship, use :ref:`ref-onetoone`.
|
To define a one-to-one relationship, use :ref:`ref-onetoone`.
|
||||||
|
|
||||||
In this example, a ``Place`` optionally can be a ``Restaurant``:
|
In this example, a ``Place`` optionally can be a ``Restaurant``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -37,6 +33,8 @@ In this example, a ``Place`` optionally can be a ``Restaurant``:
|
||||||
What follows are examples of operations that can be performed using the Python
|
What follows are examples of operations that can be performed using the Python
|
||||||
API facilities.
|
API facilities.
|
||||||
|
|
||||||
|
.. highlight:: pycon
|
||||||
|
|
||||||
Create a couple of Places::
|
Create a couple of Places::
|
||||||
|
|
||||||
>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
|
>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
|
||||||
|
|
|
@ -24,9 +24,7 @@ the alias of ``default`` when no other database has been selected.
|
||||||
|
|
||||||
The following is an example ``settings.py`` snippet defining two
|
The following is an example ``settings.py`` snippet defining two
|
||||||
databases -- a default PostgreSQL database and a MySQL database called
|
databases -- a default PostgreSQL database and a MySQL database called
|
||||||
``users``:
|
``users``::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|
|
@ -324,16 +324,12 @@ manager.
|
||||||
|
|
||||||
.. _`Python ticket #9220`: http://bugs.python.org/issue9220
|
.. _`Python ticket #9220`: http://bugs.python.org/issue9220
|
||||||
|
|
||||||
Using a cursor as a context manager:
|
Using a cursor as a context manager::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
with connection.cursor() as c:
|
with connection.cursor() as c:
|
||||||
c.execute(...)
|
c.execute(...)
|
||||||
|
|
||||||
is equivalent to:
|
is equivalent to::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
c = connection.cursor()
|
c = connection.cursor()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -554,9 +554,7 @@ Using a formset in views and templates
|
||||||
|
|
||||||
Using a formset inside a view is as easy as using a regular ``Form`` class.
|
Using a formset inside a view is as easy as using a regular ``Form`` class.
|
||||||
The only thing you will want to be aware of is making sure to use the
|
The only thing you will want to be aware of is making sure to use the
|
||||||
management form inside the template. Let's look at a sample view:
|
management form inside the template. Let's look at a sample view::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
|
@ -633,9 +631,7 @@ You are able to use more than one formset in a view if you like. Formsets
|
||||||
borrow much of its behavior from forms. With that said you are able to use
|
borrow much of its behavior from forms. With that said you are able to use
|
||||||
``prefix`` to prefix formset form field names with a given value to allow
|
``prefix`` to prefix formset form field names with a given value to allow
|
||||||
more than one formset to be sent to a view without name clashing. Lets take
|
more than one formset to be sent to a view without name clashing. Lets take
|
||||||
a look at how this might be accomplished:
|
a look at how this might be accomplished::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
|
|
|
@ -224,9 +224,7 @@ The :class:`Form` class
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
We already know what we want our HTML form to look like. Our starting point for
|
We already know what we want our HTML form to look like. Our starting point for
|
||||||
it in Django is this:
|
it in Django is this::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
|
@ -273,9 +271,7 @@ same view which published the form. This allows us to reuse some of the same
|
||||||
logic.
|
logic.
|
||||||
|
|
||||||
To handle the form we need to instantiate it in the view for the URL where we
|
To handle the form we need to instantiate it in the view for the URL where we
|
||||||
want it to be published:
|
want it to be published::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
@ -386,9 +382,7 @@ More on fields
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Consider a more useful form than our minimal example above, which we could use
|
Consider a more useful form than our minimal example above, which we could use
|
||||||
to implement "contact me" functionality on a personal Web site:
|
to implement "contact me" functionality on a personal Web site::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
|
@ -434,9 +428,7 @@ In the contact form example above, ``cc_myself`` will be a boolean value.
|
||||||
Likewise, fields such as :class:`IntegerField` and :class:`FloatField` convert
|
Likewise, fields such as :class:`IntegerField` and :class:`FloatField` convert
|
||||||
values to a Python ``int`` and ``float`` respectively.
|
values to a Python ``int`` and ``float`` respectively.
|
||||||
|
|
||||||
Here's how the form data could be processed in the view that handles this form:
|
Here's how the form data could be processed in the view that handles this form::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
|
|
@ -851,7 +851,9 @@ Saving objects in the formset
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
As with a ``ModelForm``, you can save the data as a model object. This is done
|
As with a ``ModelForm``, you can save the data as a model object. This is done
|
||||||
with the formset's ``save()`` method::
|
with the formset's ``save()`` method:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a formset instance with POST data.
|
# Create a formset instance with POST data.
|
||||||
>>> formset = AuthorFormSet(request.POST)
|
>>> formset = AuthorFormSet(request.POST)
|
||||||
|
@ -869,7 +871,9 @@ excluded), these fields will not be set by the ``save()`` method. You can find
|
||||||
more information about this restriction, which also holds for regular
|
more information about this restriction, which also holds for regular
|
||||||
``ModelForms``, in `Selecting the fields to use`_.
|
``ModelForms``, in `Selecting the fields to use`_.
|
||||||
|
|
||||||
Pass ``commit=False`` to return the unsaved model instances::
|
Pass ``commit=False`` to return the unsaved model instances:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# don't save to the database
|
# don't save to the database
|
||||||
>>> instances = formset.save(commit=False)
|
>>> instances = formset.save(commit=False)
|
||||||
|
|
|
@ -260,9 +260,7 @@ list::
|
||||||
:func:`~django.views.decorators.csrf.csrf_protect` on the function that
|
:func:`~django.views.decorators.csrf.csrf_protect` on the function that
|
||||||
actually processes the request. Note that this means that the handlers may
|
actually processes the request. Note that this means that the handlers may
|
||||||
start receiving the file upload before the CSRF checks have been done.
|
start receiving the file upload before the CSRF checks have been done.
|
||||||
Example code:
|
Example code::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.views.decorators.csrf import csrf_exempt, csrf_protect
|
from django.views.decorators.csrf import csrf_exempt, csrf_protect
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,7 @@ application directory.
|
||||||
A simple view
|
A simple view
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Here's a view that returns the current date and time, as an HTML document:
|
Here's a view that returns the current date and time, as an HTML document::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
import datetime
|
import datetime
|
||||||
|
|
|
@ -1049,6 +1049,7 @@ whenever you restart your application server.
|
||||||
from django.views.i18n import javascript_catalog
|
from django.views.i18n import javascript_catalog
|
||||||
|
|
||||||
last_modified_date = timezone.now()
|
last_modified_date = timezone.now()
|
||||||
|
|
||||||
@last_modified(lambda req, **kw: last_modified_date)
|
@last_modified(lambda req, **kw: last_modified_date)
|
||||||
def cached_javascript_catalog(request, domain='djangojs', packages=None):
|
def cached_javascript_catalog(request, domain='djangojs', packages=None):
|
||||||
return javascript_catalog(request, domain, packages)
|
return javascript_catalog(request, domain, packages)
|
||||||
|
|
|
@ -77,9 +77,7 @@ Receiver functions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
First, we need to define a receiver function. A receiver can be any Python
|
First, we need to define a receiver function. A receiver can be any Python
|
||||||
function or method:
|
function or method::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def my_callback(sender, **kwargs):
|
def my_callback(sender, **kwargs):
|
||||||
print("Request finished!")
|
print("Request finished!")
|
||||||
|
@ -106,9 +104,7 @@ Connecting receiver functions
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
There are two ways you can connect a receiver to a signal. You can take the
|
There are two ways you can connect a receiver to a signal. You can take the
|
||||||
manual connect route:
|
manual connect route::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.signals import request_finished
|
from django.core.signals import request_finished
|
||||||
|
|
||||||
|
@ -120,9 +116,7 @@ Alternatively, you can use a :func:`receiver` decorator:
|
||||||
|
|
||||||
:param signal: A signal or a list of signals to connect a function to.
|
:param signal: A signal or a list of signals to connect a function to.
|
||||||
|
|
||||||
Here's how you connect with the decorator:
|
Here's how you connect with the decorator::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.signals import request_finished
|
from django.core.signals import request_finished
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
@ -133,7 +127,6 @@ Here's how you connect with the decorator:
|
||||||
|
|
||||||
Now, our ``my_callback`` function will be called each time a request finishes.
|
Now, our ``my_callback`` function will be called each time a request finishes.
|
||||||
|
|
||||||
|
|
||||||
.. admonition:: Where should this code live?
|
.. admonition:: Where should this code live?
|
||||||
|
|
||||||
Strictly speaking, signal handling and registration code can live anywhere
|
Strictly speaking, signal handling and registration code can live anywhere
|
||||||
|
@ -167,14 +160,13 @@ when one *specific* model is saved.
|
||||||
In these cases, you can register to receive signals sent only by particular
|
In these cases, you can register to receive signals sent only by particular
|
||||||
senders. In the case of :data:`django.db.models.signals.pre_save`, the sender
|
senders. In the case of :data:`django.db.models.signals.pre_save`, the sender
|
||||||
will be the model class being saved, so you can indicate that you only want
|
will be the model class being saved, so you can indicate that you only want
|
||||||
signals sent by some model:
|
signals sent by some model::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.db.models.signals import pre_save
|
from django.db.models.signals import pre_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from myapp.models import MyModel
|
from myapp.models import MyModel
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_save, sender=MyModel)
|
@receiver(pre_save, sender=MyModel)
|
||||||
def my_handler(sender, **kwargs):
|
def my_handler(sender, **kwargs):
|
||||||
...
|
...
|
||||||
|
@ -200,9 +192,7 @@ send an email whenever a model is saved), pass a unique identifier as
|
||||||
the ``dispatch_uid`` argument to identify your receiver function. This
|
the ``dispatch_uid`` argument to identify your receiver function. This
|
||||||
identifier will usually be a string, although any hashable object will
|
identifier will usually be a string, although any hashable object will
|
||||||
suffice. The end result is that your receiver function will only be
|
suffice. The end result is that your receiver function will only be
|
||||||
bound to the signal once for each unique ``dispatch_uid`` value.
|
bound to the signal once for each unique ``dispatch_uid`` value::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.core.signals import request_finished
|
from django.core.signals import request_finished
|
||||||
|
|
||||||
|
@ -224,9 +214,7 @@ All signals are :class:`django.dispatch.Signal` instances. The
|
||||||
to listeners. This is purely documentational, however, as there is nothing that
|
to listeners. This is purely documentational, however, as there is nothing that
|
||||||
checks that the signal actually provides these arguments to its listeners.
|
checks that the signal actually provides these arguments to its listeners.
|
||||||
|
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import django.dispatch
|
import django.dispatch
|
||||||
|
|
||||||
|
@ -250,9 +238,7 @@ To send a signal, call either :meth:`Signal.send` or :meth:`Signal.send_robust`.
|
||||||
You must provide the ``sender`` argument (which is a class most of the time),
|
You must provide the ``sender`` argument (which is a class most of the time),
|
||||||
and may provide as many other keyword arguments as you like.
|
and may provide as many other keyword arguments as you like.
|
||||||
|
|
||||||
For example, here's how sending our ``pizza_done`` signal might look:
|
For example, here's how sending our ``pizza_done`` signal might look::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class PizzaStore(object):
|
class PizzaStore(object):
|
||||||
...
|
...
|
||||||
|
|
|
@ -695,9 +695,7 @@ via the :djadminopt:`--liveserver` option, for example:
|
||||||
|
|
||||||
Another way of changing the default server address is by setting the
|
Another way of changing the default server address is by setting the
|
||||||
`DJANGO_LIVE_TEST_SERVER_ADDRESS` environment variable somewhere in your
|
`DJANGO_LIVE_TEST_SERVER_ADDRESS` environment variable somewhere in your
|
||||||
code (for example, in a :ref:`custom test runner<topics-testing-test_runner>`):
|
code (for example, in a :ref:`custom test runner<topics-testing-test_runner>`)::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8082'
|
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8082'
|
||||||
|
@ -727,9 +725,7 @@ Python path:
|
||||||
pip install selenium
|
pip install selenium
|
||||||
|
|
||||||
Then, add a ``LiveServerTestCase``-based test to your app's tests module
|
Then, add a ``LiveServerTestCase``-based test to your app's tests module
|
||||||
(for example: ``myapp/tests.py``). The code for this test may look as follows:
|
(for example: ``myapp/tests.py``). The code for this test may look as follows::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from django.test import LiveServerTestCase
|
from django.test import LiveServerTestCase
|
||||||
from selenium.webdriver.firefox.webdriver import WebDriver
|
from selenium.webdriver.firefox.webdriver import WebDriver
|
||||||
|
@ -805,9 +801,7 @@ out the `full reference`_ for more details.
|
||||||
need to check that a response is received by Selenium and that the next
|
need to check that a response is received by Selenium and that the next
|
||||||
page is loaded before proceeding with further test execution.
|
page is loaded before proceeding with further test execution.
|
||||||
Do this, for example, by making Selenium wait until the ``<body>`` HTML tag
|
Do this, for example, by making Selenium wait until the ``<body>`` HTML tag
|
||||||
is found in the response (requires Selenium > 2.13):
|
is found in the response (requires Selenium > 2.13)::
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def test_login(self):
|
def test_login(self):
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
|
|
Loading…
Reference in New Issue