mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Refs #36485 -- Rewrapped docs to 79 columns line length.
Lines in the docs files were manually adjusted to conform to the 79 columns limit per line (plus newline), improving readability and consistency across the content.
This commit is contained in:
@@ -230,8 +230,8 @@ its own thread).
|
||||
|
||||
The async context can be imposed upon you by the environment in which you are
|
||||
running your Django code. For example, Jupyter_ notebooks and IPython_
|
||||
interactive shells both transparently provide an active event loop so that it is
|
||||
easier to interact with asynchronous APIs.
|
||||
interactive shells both transparently provide an active event loop so that it
|
||||
is easier to interact with asynchronous APIs.
|
||||
|
||||
If you're using an IPython shell, you can disable this event loop by running:
|
||||
|
||||
|
||||
@@ -81,8 +81,8 @@ backends that follow.
|
||||
for the duration of that session whenever access to the currently
|
||||
authenticated user is needed. This effectively means that authentication
|
||||
sources are cached on a per-session basis, so if you change
|
||||
:setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
|
||||
you need to force users to re-authenticate using different methods. A
|
||||
:setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data
|
||||
if you need to force users to re-authenticate using different methods. A
|
||||
simple way to do that is to execute ``Session.objects.all().delete()``.
|
||||
|
||||
Writing an authentication backend
|
||||
@@ -474,8 +474,8 @@ different user model.
|
||||
Instead of referring to :class:`~django.contrib.auth.models.User` directly,
|
||||
you should reference the user model using
|
||||
``django.contrib.auth.get_user_model()``. This method will return the
|
||||
currently active user model -- the custom user model if one is specified, or
|
||||
:class:`~django.contrib.auth.models.User` otherwise.
|
||||
currently active user model -- the custom user model if one is specified,
|
||||
or :class:`~django.contrib.auth.models.User` otherwise.
|
||||
|
||||
When you define a foreign key or many-to-many relations to the user model,
|
||||
you should specify the custom model using the :setting:`AUTH_USER_MODEL`
|
||||
@@ -491,8 +491,8 @@ different user model.
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
When connecting to signals sent by the user model, you should specify
|
||||
the custom model using the :setting:`AUTH_USER_MODEL` setting. For example::
|
||||
When connecting to signals sent by the user model, you should specify the
|
||||
custom model using the :setting:`AUTH_USER_MODEL` setting. For example::
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import post_save
|
||||
@@ -682,9 +682,9 @@ The following attributes and methods are available on any subclass of
|
||||
.. attribute:: models.AbstractBaseUser.is_anonymous
|
||||
|
||||
Read-only attribute which is always ``False``. This is a way of
|
||||
differentiating :class:`~models.User` and :class:`~models.AnonymousUser`
|
||||
objects. Generally, you should prefer using
|
||||
:attr:`~models.User.is_authenticated` to this attribute.
|
||||
differentiating :class:`~models.User` and
|
||||
:class:`~models.AnonymousUser` objects. Generally, you should prefer
|
||||
using :attr:`~models.User.is_authenticated` to this attribute.
|
||||
|
||||
.. method:: models.AbstractBaseUser.set_password(raw_password)
|
||||
|
||||
@@ -710,8 +710,8 @@ The following attributes and methods are available on any subclass of
|
||||
|
||||
Marks the user as having no password set. This isn't the same as
|
||||
having a blank string for a password.
|
||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.check_password` for this user
|
||||
will never return ``True``. Doesn't save the
|
||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.check_password` for
|
||||
this user will never return ``True``. Doesn't save the
|
||||
:class:`~django.contrib.auth.models.AbstractBaseUser` object.
|
||||
|
||||
You may need this if authentication for your application takes place
|
||||
@@ -720,8 +720,8 @@ The following attributes and methods are available on any subclass of
|
||||
.. method:: models.AbstractBaseUser.has_usable_password()
|
||||
|
||||
Returns ``False`` if
|
||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.set_unusable_password` has
|
||||
been called for this user.
|
||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.set_unusable_password`
|
||||
has been called for this user.
|
||||
|
||||
.. method:: models.AbstractBaseUser.get_session_auth_hash()
|
||||
|
||||
@@ -751,8 +751,9 @@ defines ``username``, ``email``, ``is_staff``, ``is_active``, ``is_superuser``,
|
||||
``last_login``, and ``date_joined`` fields the same as Django's default user,
|
||||
you can install Django's :class:`~django.contrib.auth.models.UserManager`;
|
||||
however, if your user model defines different fields, you'll need to define a
|
||||
custom manager that extends :class:`~django.contrib.auth.models.BaseUserManager`
|
||||
providing two additional methods:
|
||||
custom manager that extends
|
||||
:class:`~django.contrib.auth.models.BaseUserManager` providing two additional
|
||||
methods:
|
||||
|
||||
.. class:: models.CustomUserManager
|
||||
|
||||
@@ -808,10 +809,11 @@ utility methods:
|
||||
Extending Django's default ``User``
|
||||
-----------------------------------
|
||||
|
||||
If you're entirely happy with Django's :class:`~django.contrib.auth.models.User`
|
||||
model, but you want to add some additional profile information, you could
|
||||
subclass :class:`django.contrib.auth.models.AbstractUser` and add your custom
|
||||
profile fields, although we'd recommend a separate model as described in
|
||||
If you're entirely happy with Django's
|
||||
:class:`~django.contrib.auth.models.User` model, but you want to add some
|
||||
additional profile information, you could subclass
|
||||
:class:`django.contrib.auth.models.AbstractUser` and add your custom profile
|
||||
fields, although we'd recommend a separate model as described in
|
||||
:ref:`specifying-custom-user-model`. ``AbstractUser`` provides the full
|
||||
implementation of the default :class:`~django.contrib.auth.models.User` as an
|
||||
:ref:`abstract model <abstract-base-classes>`.
|
||||
|
||||
@@ -1042,8 +1042,8 @@ arguments in the URLconf, these will be passed on to the view. For example::
|
||||
),
|
||||
]
|
||||
|
||||
All views are :doc:`class-based </topics/class-based-views/index>`, which allows
|
||||
you to easily customize them by subclassing.
|
||||
All views are :doc:`class-based </topics/class-based-views/index>`, which
|
||||
allows you to easily customize them by subclassing.
|
||||
|
||||
.. _all-authentication-views:
|
||||
|
||||
@@ -1155,8 +1155,8 @@ implementation details see :ref:`using-the-views`.
|
||||
For more on sites, see :doc:`/ref/contrib/sites`.
|
||||
|
||||
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
|
||||
the ``as_view`` method in your URLconf. For example, this URLconf line would
|
||||
you can pass the ``template_name`` parameter via the extra arguments to the
|
||||
``as_view`` method in your URLconf. For example, this URLconf line would
|
||||
use :file:`myapp/login.html` instead::
|
||||
|
||||
path("accounts/login/", auth_views.LoginView.as_view(template_name="myapp/login.html")),
|
||||
@@ -1799,8 +1799,8 @@ the logged-in user has any permissions in the ``foo`` app:
|
||||
{% if perms.foo %}
|
||||
|
||||
Evaluating a two-level-attribute lookup as a boolean is a proxy to
|
||||
:meth:`User.has_perm() <django.contrib.auth.models.User.has_perm>`. For example,
|
||||
to check if the logged-in user has the permission ``foo.add_vote``:
|
||||
:meth:`User.has_perm() <django.contrib.auth.models.User.has_perm>`. For
|
||||
example, to check if the logged-in user has the permission ``foo.add_vote``:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ hashing. This deliberately slows down attackers, making attacks against hashed
|
||||
passwords harder. However, as computing power increases, the number of
|
||||
iterations needs to be increased. We've chosen a reasonable default (and will
|
||||
increase it with each release of Django), but you may wish to tune it up or
|
||||
down, depending on your security needs and available processing power. To do so,
|
||||
you'll subclass the appropriate algorithm and override the ``iterations``
|
||||
down, depending on your security needs and available processing power. To do
|
||||
so, you'll subclass the appropriate algorithm and override the ``iterations``
|
||||
parameter (use the ``rounds`` parameter when subclassing a bcrypt hasher). For
|
||||
example, to increase the number of iterations used by the default PBKDF2
|
||||
algorithm:
|
||||
|
||||
@@ -92,8 +92,8 @@ To use Memcached with Django:
|
||||
port on which Memcached is running, or to a ``unix:path`` value, where
|
||||
``path`` is the path to a Memcached Unix socket file.
|
||||
|
||||
In this example, Memcached is running on localhost (127.0.0.1) port 11211, using
|
||||
the ``pymemcache`` binding::
|
||||
In this example, Memcached is running on localhost (127.0.0.1) port 11211,
|
||||
using the ``pymemcache`` binding::
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
@@ -188,7 +188,7 @@ To use Redis as your cache backend with Django:
|
||||
* Set :setting:`LOCATION <CACHES-LOCATION>` to the URL pointing to your Redis
|
||||
instance, using the appropriate scheme. See the ``redis-py`` docs for
|
||||
`details on the available schemes
|
||||
<https://redis-py.readthedocs.io/en/stable/connections.html#redis.connection.ConnectionPool.from_url>`_.
|
||||
<https://redis-py.readthedocs.io/en/stable/connections.html#redis.connection.ConnectionPool.from_url>`__.
|
||||
|
||||
For example, if Redis is running on localhost (127.0.0.1) port 6379::
|
||||
|
||||
@@ -391,11 +391,11 @@ Local-memory caching
|
||||
--------------------
|
||||
|
||||
This is the default cache if another is not specified in your settings file. If
|
||||
you want the speed advantages of in-memory caching but don't have the capability
|
||||
of running Memcached, consider the local-memory cache backend. This cache is
|
||||
per-process (see below) and thread-safe. To use it, set :setting:`BACKEND
|
||||
<CACHES-BACKEND>` to ``"django.core.cache.backends.locmem.LocMemCache"``. For
|
||||
example::
|
||||
you want the speed advantages of in-memory caching but don't have the
|
||||
capability of running Memcached, consider the local-memory cache backend. This
|
||||
cache is per-process (see below) and thread-safe. To use it, set
|
||||
:setting:`BACKEND <CACHES-BACKEND>` to
|
||||
``"django.core.cache.backends.locmem.LocMemCache"``. For example::
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
@@ -470,10 +470,10 @@ behavior. These arguments are provided as additional keys in the
|
||||
:setting:`CACHES` setting. Valid arguments are as follows:
|
||||
|
||||
* :setting:`TIMEOUT <CACHES-TIMEOUT>`: The default timeout, in
|
||||
seconds, to use for the cache. This argument defaults to ``300`` seconds (5 minutes).
|
||||
You can set ``TIMEOUT`` to ``None`` so that, by default, cache keys never
|
||||
expire. A value of ``0`` causes keys to immediately expire (effectively
|
||||
"don't cache").
|
||||
seconds, to use for the cache. This argument defaults to ``300`` seconds
|
||||
(5 minutes). You can set ``TIMEOUT`` to ``None`` so that, by default, cache
|
||||
keys never expire. A value of ``0`` causes keys to immediately expire
|
||||
(effectively "don't cache").
|
||||
|
||||
* :setting:`OPTIONS <CACHES-OPTIONS>`: Any options that should be
|
||||
passed to the cache backend. The list of valid options will vary
|
||||
@@ -623,11 +623,11 @@ Then, add the following required settings to your Django settings file:
|
||||
prevent key collisions. Use an empty string if you don't care.
|
||||
|
||||
``FetchFromCacheMiddleware`` caches GET and HEAD responses with status 200,
|
||||
where the request and response headers allow. Responses to requests for the same
|
||||
URL with different query parameters are considered to be unique pages and are
|
||||
cached separately. This middleware expects that a HEAD request is answered with
|
||||
the same response headers as the corresponding GET request; in which case it can
|
||||
return a cached GET response for HEAD request.
|
||||
where the request and response headers allow. Responses to requests for the
|
||||
same URL with different query parameters are considered to be unique pages and
|
||||
are cached separately. This middleware expects that a HEAD request is answered
|
||||
with the same response headers as the corresponding GET request; in which case
|
||||
it can return a cached GET response for HEAD request.
|
||||
|
||||
Additionally, ``UpdateCacheMiddleware`` automatically sets a few headers in
|
||||
each :class:`~django.http.HttpResponse` which affect :ref:`downstream caches
|
||||
@@ -732,8 +732,8 @@ approach couples your view to the cache system, which is not ideal for several
|
||||
reasons. For instance, you might want to reuse the view functions on another,
|
||||
cache-less site, or you might want to distribute the views to people who might
|
||||
want to use them without being cached. The solution to these problems is to
|
||||
specify the per-view cache in the URLconf rather than next to the view functions
|
||||
themselves.
|
||||
specify the per-view cache in the URLconf rather than next to the view
|
||||
functions themselves.
|
||||
|
||||
You can do so by wrapping the view function with ``cache_page`` when you refer
|
||||
to it in the URLconf. Here's the old URLconf from earlier::
|
||||
@@ -773,11 +773,11 @@ example:
|
||||
{% endcache %}
|
||||
|
||||
Sometimes you might want to cache multiple copies of a fragment depending on
|
||||
some dynamic data that appears inside the fragment. For example, you might want a
|
||||
separate cached copy of the sidebar used in the previous example for every user
|
||||
of your site. Do this by passing one or more additional arguments, which may be
|
||||
variables with or without filters, to the ``{% cache %}`` template tag to
|
||||
uniquely identify the cache fragment:
|
||||
some dynamic data that appears inside the fragment. For example, you might want
|
||||
a separate cached copy of the sidebar used in the previous example for every
|
||||
user of your site. Do this by passing one or more additional arguments, which
|
||||
may be variables with or without filters, to the ``{% cache %}`` template tag
|
||||
to uniquely identify the cache fragment:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
@@ -816,10 +816,10 @@ equivalent:
|
||||
This feature is useful in avoiding repetition in templates. You can set the
|
||||
timeout in a variable, in one place, and reuse that value.
|
||||
|
||||
By default, the cache tag will try to use the cache called "template_fragments".
|
||||
If no such cache exists, it will fall back to using the default cache. You may
|
||||
select an alternate cache backend to use with the ``using`` keyword argument,
|
||||
which must be the last argument to the tag.
|
||||
By default, the cache tag will try to use the cache called
|
||||
"template_fragments". If no such cache exists, it will fall back to using the
|
||||
default cache. You may select an alternate cache backend to use with the
|
||||
``using`` keyword argument, which must be the last argument to the tag.
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
@@ -830,10 +830,10 @@ It is considered an error to specify a cache name that is not configured.
|
||||
.. function:: django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None)
|
||||
|
||||
If you want to obtain the cache key used for a cached fragment, you can use
|
||||
``make_template_fragment_key``. ``fragment_name`` is the same as second argument
|
||||
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
|
||||
a cached item, for example:
|
||||
``make_template_fragment_key``. ``fragment_name`` is the same as second
|
||||
argument 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 a cached item, for example:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -1013,8 +1013,8 @@ actually exist in the cache (and haven't expired):
|
||||
|
||||
.. method:: cache.set_many(dict, timeout)
|
||||
|
||||
To set multiple values more efficiently, use ``set_many()`` to pass a dictionary
|
||||
of key-value pairs:
|
||||
To set multiple values more efficiently, use ``set_many()`` to pass a
|
||||
dictionary of key-value pairs:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -1382,8 +1382,9 @@ are equivalent::
|
||||
The headers you pass to ``vary_on_headers`` are not case sensitive;
|
||||
``"User-Agent"`` is the same thing as ``"user-agent"``.
|
||||
|
||||
You can also use a helper function, :func:`django.utils.cache.patch_vary_headers`,
|
||||
directly. This function sets, or adds to, the ``Vary header``. For example::
|
||||
You can also use a helper function,
|
||||
:func:`django.utils.cache.patch_vary_headers`, directly. This function sets, or
|
||||
adds to, the ``Vary header``. For example::
|
||||
|
||||
from django.shortcuts import render
|
||||
from django.utils.cache import patch_vary_headers
|
||||
|
||||
@@ -15,9 +15,10 @@ WSGI stack that is used in deployment. If you need to run system checks on your
|
||||
deployment server, trigger them explicitly using :djadmin:`check`.
|
||||
|
||||
Serious errors will prevent Django commands (such as :djadmin:`runserver`) from
|
||||
running at all. Minor problems are reported to the console. If you have inspected
|
||||
the cause of a warning and are happy to ignore it, you can hide specific warnings
|
||||
using the :setting:`SILENCED_SYSTEM_CHECKS` setting in your project settings file.
|
||||
running at all. Minor problems are reported to the console. If you have
|
||||
inspected the cause of a warning and are happy to ignore it, you can hide
|
||||
specific warnings using the :setting:`SILENCED_SYSTEM_CHECKS` setting in your
|
||||
project settings file.
|
||||
|
||||
A full list of all checks that can be raised by Django can be found in the
|
||||
:doc:`System check reference </ref/checks>`.
|
||||
@@ -61,8 +62,8 @@ The ``**kwargs`` argument is required for future expansion.
|
||||
Messages
|
||||
--------
|
||||
|
||||
The function must return a list of messages. If no problems are found as a result
|
||||
of the check, the check function must return an empty list.
|
||||
The function must return a list of messages. If no problems are found as a
|
||||
result of the check, the check function must return an empty list.
|
||||
|
||||
The warnings and errors raised by the check method must be instances of
|
||||
:class:`~django.core.checks.CheckMessage`. An instance of
|
||||
@@ -145,9 +146,9 @@ delegate each check to separate methods.
|
||||
|
||||
Consider an example where you are implementing a custom field named
|
||||
``RangedIntegerField``. This field adds ``min`` and ``max`` arguments to the
|
||||
constructor of ``IntegerField``. You may want to add a check to ensure that users
|
||||
provide a min value that is less than or equal to the max value. The following
|
||||
code snippet shows how you can implement this check::
|
||||
constructor of ``IntegerField``. You may want to add a check to ensure that
|
||||
users provide a min value that is less than or equal to the max value. The
|
||||
following code snippet shows how you can implement this check::
|
||||
|
||||
from django.core import checks
|
||||
from django.db import models
|
||||
@@ -186,7 +187,8 @@ If you wanted to add checks to a model manager, you would take the same
|
||||
approach on your subclass of :class:`~django.db.models.Manager`.
|
||||
|
||||
If you want to add a check to a model class, the approach is *almost* the same:
|
||||
the only difference is that the check is a classmethod, not an instance method::
|
||||
the only difference is that the check is a classmethod, not an instance
|
||||
method::
|
||||
|
||||
class MyModel(models.Model):
|
||||
@classmethod
|
||||
|
||||
@@ -4,8 +4,8 @@ Built-in class-based generic views
|
||||
|
||||
Writing web applications can be monotonous, because we repeat certain patterns
|
||||
again and again. Django tries to take away some of that monotony at the model
|
||||
and template layers, but web developers also experience this boredom at the view
|
||||
level.
|
||||
and template layers, but web developers also experience this boredom at the
|
||||
view level.
|
||||
|
||||
Django's *generic views* were developed to ease that pain. They take certain
|
||||
common idioms and patterns found in view development and abstract them so that
|
||||
@@ -229,8 +229,8 @@ you can override it to send more::
|
||||
Generally, ``get_context_data`` will merge the context data of all parent
|
||||
classes with those of the current class. To preserve this behavior in your
|
||||
own classes where you want to alter the context, you should be sure to call
|
||||
``get_context_data`` on the super class. When no two classes try to define the
|
||||
same key, this will give the expected results. However if any class
|
||||
``get_context_data`` on the super class. When no two classes try to define
|
||||
the same key, this will give the expected results. However if any class
|
||||
attempts to override a key after parent classes have set it (after the call
|
||||
to super), any children of that class will also need to explicitly set it
|
||||
after super if they want to be sure to override all parents. If you're
|
||||
@@ -295,8 +295,8 @@ list of books by a particular publisher, you can use the same technique::
|
||||
template_name = "books/acme_list.html"
|
||||
|
||||
Notice that along with a filtered ``queryset``, we're also using a custom
|
||||
template name. If we didn't, the generic view would use the same template as the
|
||||
"vanilla" object list, which might not be what we want.
|
||||
template name. If we didn't, the generic view would use the same template as
|
||||
the "vanilla" object list, which might not be what we want.
|
||||
|
||||
Also notice that this isn't a very elegant way of doing publisher-specific
|
||||
books. If we want to add another publisher page, we'd need another handful of
|
||||
@@ -317,8 +317,8 @@ Dynamic filtering
|
||||
|
||||
Another common need is to filter down the objects given in a list page by some
|
||||
key in the URL. Earlier we hardcoded the publisher's name in the URLconf, but
|
||||
what if we wanted to write a view that displayed all the books by some arbitrary
|
||||
publisher?
|
||||
what if we wanted to write a view that displayed all the books by some
|
||||
arbitrary publisher?
|
||||
|
||||
Handily, the ``ListView`` has a
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset` method we
|
||||
|
||||
@@ -84,7 +84,8 @@ special requirements; see below for examples.
|
||||
You don't even need to provide a ``success_url`` for
|
||||
:class:`~django.views.generic.edit.CreateView` or
|
||||
:class:`~django.views.generic.edit.UpdateView` - they will use
|
||||
:meth:`~django.db.models.Model.get_absolute_url` on the model object if available.
|
||||
:meth:`~django.db.models.Model.get_absolute_url` on the model object if
|
||||
available.
|
||||
|
||||
If you want to use a custom :class:`~django.forms.ModelForm` (for instance to
|
||||
add extra validation), set
|
||||
@@ -146,8 +147,9 @@ inner ``Meta`` class on :class:`~django.forms.ModelForm`. Unless you define the
|
||||
form class in another way, the attribute is required and the view will raise
|
||||
an :exc:`~django.core.exceptions.ImproperlyConfigured` exception if it's not.
|
||||
|
||||
If you specify both the :attr:`~django.views.generic.edit.ModelFormMixin.fields`
|
||||
and :attr:`~django.views.generic.edit.FormMixin.form_class` attributes, an
|
||||
If you specify both the
|
||||
:attr:`~django.views.generic.edit.ModelFormMixin.fields` and
|
||||
:attr:`~django.views.generic.edit.FormMixin.form_class` attributes, an
|
||||
:exc:`~django.core.exceptions.ImproperlyConfigured` exception will be raised.
|
||||
|
||||
Finally, we hook these new views into the URLconf:
|
||||
|
||||
@@ -23,8 +23,8 @@ Basic examples
|
||||
==============
|
||||
|
||||
Django provides base view classes which will suit a wide range of applications.
|
||||
All views inherit from the :class:`~django.views.generic.base.View` class, which
|
||||
handles linking the view into the URLs, HTTP method dispatching and other
|
||||
All views inherit from the :class:`~django.views.generic.base.View` class,
|
||||
which handles linking the view into the URLs, HTTP method dispatching and other
|
||||
common features. :class:`~django.views.generic.base.RedirectView` provides a
|
||||
HTTP redirect, and :class:`~django.views.generic.base.TemplateView` extends the
|
||||
base class to make it also render a template.
|
||||
@@ -84,7 +84,8 @@ method instead, which provides a function-like entry to class-based views::
|
||||
|
||||
|
||||
For more information on how to use the built in generic views, consult the next
|
||||
topic on :doc:`generic class-based views</topics/class-based-views/generic-display>`.
|
||||
topic on
|
||||
:doc:`generic class-based views</topics/class-based-views/generic-display>`.
|
||||
|
||||
.. _supporting-other-http-methods:
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ The relationship and history of generic views, class-based views, and class-base
|
||||
|
||||
In the beginning there was only the view function contract, Django passed your
|
||||
function an :class:`~django.http.HttpRequest` and expected back an
|
||||
:class:`~django.http.HttpResponse`. This was the extent of what Django provided.
|
||||
:class:`~django.http.HttpResponse`. This was the extent of what Django
|
||||
provided.
|
||||
|
||||
Early on it was recognized that there were common idioms and patterns found in
|
||||
view development. Function-based generic views were introduced to abstract
|
||||
|
||||
@@ -112,11 +112,10 @@ context data for template renders.
|
||||
|
||||
To then make a :class:`~django.template.response.TemplateResponse`,
|
||||
:class:`DetailView` uses
|
||||
:class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`,
|
||||
which extends :class:`~django.views.generic.base.TemplateResponseMixin`,
|
||||
overriding
|
||||
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names`
|
||||
as discussed above. It actually provides a fairly sophisticated set of options,
|
||||
:class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`, which
|
||||
extends :class:`~django.views.generic.base.TemplateResponseMixin`, overriding
|
||||
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names` as
|
||||
discussed above. It actually provides a fairly sophisticated set of options,
|
||||
but the main one that most people are going to use is
|
||||
``<app_label>/<model_name>_detail.html``. The ``_detail`` part can be changed
|
||||
by setting
|
||||
@@ -135,20 +134,18 @@ paginated) list of objects, typically a
|
||||
using that list of objects.
|
||||
|
||||
To get the objects, :class:`~django.views.generic.list.ListView` uses
|
||||
:class:`~django.views.generic.list.MultipleObjectMixin`, which
|
||||
provides both
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset`
|
||||
and
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.paginate_queryset`. Unlike
|
||||
with :class:`~django.views.generic.detail.SingleObjectMixin`, there's no need
|
||||
to key off parts of the URL to figure out the queryset to work with, so the
|
||||
default uses the
|
||||
:class:`~django.views.generic.list.MultipleObjectMixin`, which provides both
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset` and
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.paginate_queryset`.
|
||||
Unlike with :class:`~django.views.generic.detail.SingleObjectMixin`, there's no
|
||||
need to key off parts of the URL to figure out the queryset to work with, so
|
||||
the default uses the
|
||||
:attr:`~django.views.generic.list.MultipleObjectMixin.queryset` or
|
||||
:attr:`~django.views.generic.list.MultipleObjectMixin.model` attribute
|
||||
on the view class. A common reason to override
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset`
|
||||
here would be to dynamically vary the objects, such as depending on
|
||||
the current user or to exclude posts in the future for a blog.
|
||||
:attr:`~django.views.generic.list.MultipleObjectMixin.model` attribute on the
|
||||
view class. A common reason to override
|
||||
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset` here would
|
||||
be to dynamically vary the objects, such as depending on the current user or to
|
||||
exclude posts in the future for a blog.
|
||||
|
||||
:class:`~django.views.generic.list.MultipleObjectMixin` also overrides
|
||||
:meth:`~django.views.generic.base.ContextMixin.get_context_data` to
|
||||
@@ -159,13 +156,12 @@ it.
|
||||
|
||||
To make a :class:`~django.template.response.TemplateResponse`,
|
||||
:class:`ListView` then uses
|
||||
:class:`~django.views.generic.list.MultipleObjectTemplateResponseMixin`;
|
||||
as with :class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`
|
||||
:class:`~django.views.generic.list.MultipleObjectTemplateResponseMixin`; as
|
||||
with :class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`
|
||||
above, this overrides ``get_template_names()`` to provide :meth:`a range of
|
||||
options <django.views.generic.list.MultipleObjectTemplateResponseMixin>`,
|
||||
with the most commonly-used being
|
||||
``<app_label>/<model_name>_list.html``, with the ``_list`` part again
|
||||
being taken from the
|
||||
options <django.views.generic.list.MultipleObjectTemplateResponseMixin>`, with
|
||||
the most commonly-used being ``<app_label>/<model_name>_list.html``, with the
|
||||
``_list`` part again being taken from the
|
||||
:attr:`~django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix`
|
||||
attribute. (The date based generic views use suffixes such as ``_archive``,
|
||||
``_archive_year`` and so on to use different templates for the various
|
||||
@@ -635,8 +631,9 @@ For example, a JSON mixin might look something like this::
|
||||
information on how to correctly transform Django models and querysets into
|
||||
JSON.
|
||||
|
||||
This mixin provides a ``render_to_json_response()`` method with the same signature
|
||||
as :func:`~django.views.generic.base.TemplateResponseMixin.render_to_response`.
|
||||
This mixin provides a ``render_to_json_response()`` method with the same
|
||||
signature as
|
||||
:func:`~django.views.generic.base.TemplateResponseMixin.render_to_response`.
|
||||
To use it, we need to mix it into a ``TemplateView`` for example, and override
|
||||
``render_to_response()`` to call ``render_to_json_response()`` instead::
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ used for all HTTP methods (``POST``, ``PUT``, ``DELETE``, etc.).
|
||||
For each page (response) that Django sends back from a view, it might provide
|
||||
two HTTP headers: the ``ETag`` header and the ``Last-Modified`` header. These
|
||||
headers are optional on HTTP responses. They can be set by your view function,
|
||||
or you can rely on the :class:`~django.middleware.http.ConditionalGetMiddleware`
|
||||
middleware to set the ``ETag`` header.
|
||||
or you can rely on the
|
||||
:class:`~django.middleware.http.ConditionalGetMiddleware` middleware to set the
|
||||
``ETag`` header.
|
||||
|
||||
When the client next requests the same resource, it might send along a header
|
||||
such as either :rfc:`If-Modified-Since <9110#section-13.1.3>` or
|
||||
|
||||
@@ -4,12 +4,12 @@ Aggregation
|
||||
|
||||
.. currentmodule:: django.db.models
|
||||
|
||||
The topic guide on :doc:`Django's database-abstraction API </topics/db/queries>`
|
||||
described the way that you can use Django queries that create,
|
||||
retrieve, update and delete individual objects. However, sometimes you will
|
||||
need to retrieve values that are derived by summarizing or *aggregating* a
|
||||
collection of objects. This topic guide describes the ways that aggregate values
|
||||
can be generated and returned using Django queries.
|
||||
The topic guide on :doc:`Django's database-abstraction API
|
||||
</topics/db/queries>` described the way that you can use Django queries that
|
||||
create, retrieve, update and delete individual objects. However, sometimes you
|
||||
will need to retrieve values that are derived by summarizing or *aggregating* a
|
||||
collection of objects. This topic guide describes the ways that aggregate
|
||||
values can be generated and returned using Django queries.
|
||||
|
||||
Throughout this guide, we'll refer to the following models. These models are
|
||||
used to track the inventory for a series of online bookstores:
|
||||
@@ -322,12 +322,14 @@ We can also ask for the oldest book of any of those managed by every publisher:
|
||||
>>> Publisher.objects.aggregate(oldest_pubdate=Min("book__pubdate"))
|
||||
|
||||
(The resulting dictionary will have a key called ``'oldest_pubdate'``. If no
|
||||
such alias were specified, it would be the rather long ``'book__pubdate__min'``.)
|
||||
such alias were specified, it would be the rather long
|
||||
``'book__pubdate__min'``.)
|
||||
|
||||
This doesn't apply just to foreign keys. It also works with many-to-many
|
||||
relations. For example, we can ask for every author, annotated with the total
|
||||
number of pages considering all the books the author has (co-)authored (note how we
|
||||
use ``'book'`` to specify the ``Author`` -> ``Book`` reverse many-to-many hop):
|
||||
number of pages considering all the books the author has (co-)authored (note
|
||||
how we use ``'book'`` to specify the ``Author`` -> ``Book`` reverse
|
||||
many-to-many hop):
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -345,7 +347,8 @@ file:
|
||||
>>> Author.objects.aggregate(average_rating=Avg("book__rating"))
|
||||
|
||||
(The resulting dictionary will have a key called ``'average_rating'``. If no
|
||||
such alias were specified, it would be the rather long ``'book__rating__avg'``.)
|
||||
such alias were specified, it would be the rather long
|
||||
``'book__rating__avg'``.)
|
||||
|
||||
Aggregations and other ``QuerySet`` clauses
|
||||
===========================================
|
||||
@@ -527,7 +530,8 @@ rating of books written by each author:
|
||||
This will return one result for each author in the database, annotated with
|
||||
their average book rating.
|
||||
|
||||
However, the result will be slightly different if you use a ``values()`` clause:
|
||||
However, the result will be slightly different if you use a ``values()``
|
||||
clause:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
||||
@@ -161,8 +161,8 @@ The :meth:`~django.db.models.query.QuerySet.count` function respects
|
||||
>>> Article.objects.filter(publications__in=[p1, p2]).distinct()
|
||||
<QuerySet [<Article: Django lets you build web apps easily>, <Article: NASA uses Python>]>
|
||||
|
||||
Reverse m2m queries are supported (i.e., starting at the table that doesn't have
|
||||
a :class:`~django.db.models.ManyToManyField`):
|
||||
Reverse m2m queries are supported (i.e., starting at the table that doesn't
|
||||
have a :class:`~django.db.models.ManyToManyField`):
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
Many-to-one relationships
|
||||
=========================
|
||||
|
||||
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`.
|
||||
|
||||
In this example, a ``Reporter`` can be associated with many ``Article``
|
||||
objects, but an ``Article`` can only have one ``Reporter`` object::
|
||||
@@ -229,8 +230,8 @@ Queries can go round in circles:
|
||||
<QuerySet [<Reporter: John Smith>]>
|
||||
|
||||
If you delete a reporter, their articles will be deleted (assuming that the
|
||||
ForeignKey was defined with :attr:`django.db.models.ForeignKey.on_delete` set to
|
||||
``CASCADE``, which is the default):
|
||||
ForeignKey was defined with :attr:`django.db.models.ForeignKey.on_delete` set
|
||||
to ``CASCADE``, which is the default):
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
||||
@@ -139,7 +139,8 @@ Restaurants:
|
||||
>>> Place.objects.order_by("name")
|
||||
<QuerySet [<Place: Ace Hardware the place>, <Place: Demon Dogs the place>]>
|
||||
|
||||
You can query the models using :ref:`lookups across relationships <lookups-that-span-relationships>`:
|
||||
You can query the models using :ref:`lookups across relationships
|
||||
<lookups-that-span-relationships>`:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ The wrappers are modeled after :doc:`middleware </topics/http/middleware>` --
|
||||
they are callables which take another callable as one of their arguments. They
|
||||
call that callable to invoke the (possibly wrapped) database query, and they
|
||||
can do what they want around that call. They are, however, created and
|
||||
installed by user code, and so don't need a separate factory like middleware do.
|
||||
installed by user code, and so don't need a separate factory like middleware
|
||||
do.
|
||||
|
||||
Installing a wrapper is done in a context manager -- so the wrappers are
|
||||
temporary and specific to some flow in your code.
|
||||
|
||||
@@ -159,8 +159,9 @@ For example::
|
||||
authors = AuthorManager()
|
||||
editors = EditorManager()
|
||||
|
||||
This example allows you to request ``Person.authors.all()``, ``Person.editors.all()``,
|
||||
and ``Person.people.all()``, yielding predictable results.
|
||||
This example allows you to request ``Person.authors.all()``,
|
||||
``Person.editors.all()``, and ``Person.people.all()``, yielding predictable
|
||||
results.
|
||||
|
||||
.. _default-managers:
|
||||
|
||||
@@ -260,8 +261,8 @@ custom ``QuerySet`` if you also implement them on the ``Manager``::
|
||||
role = models.CharField(max_length=1, choices={"A": _("Author"), "E": _("Editor")})
|
||||
people = PersonManager()
|
||||
|
||||
This example allows you to call both ``authors()`` and ``editors()`` directly from
|
||||
the manager ``Person.people``.
|
||||
This example allows you to call both ``authors()`` and ``editors()`` directly
|
||||
from the manager ``Person.people``.
|
||||
|
||||
.. _create-manager-with-queryset-methods:
|
||||
|
||||
@@ -290,7 +291,8 @@ Methods are copied according to the following rules:
|
||||
|
||||
- Public methods are copied by default.
|
||||
- Private methods (starting with an underscore) are not copied by default.
|
||||
- Methods with a ``queryset_only`` attribute set to ``False`` are always copied.
|
||||
- Methods with a ``queryset_only`` attribute set to ``False`` are always
|
||||
copied.
|
||||
- Methods with a ``queryset_only`` attribute set to ``True`` are never copied.
|
||||
|
||||
For example::
|
||||
@@ -401,10 +403,10 @@ still available, since it's inherited, but isn't used as the default.
|
||||
|
||||
Finally for this example, suppose you want to add extra managers to the child
|
||||
class, but still use the default from ``AbstractBase``. You can't add the new
|
||||
manager directly in the child class, as that would override the default and you would
|
||||
have to also explicitly include all the managers from the abstract base class.
|
||||
The solution is to put the extra managers in another base class and introduce
|
||||
it into the inheritance hierarchy *after* the defaults::
|
||||
manager directly in the child class, as that would override the default and you
|
||||
would have to also explicitly include all the managers from the abstract base
|
||||
class. The solution is to put the extra managers in another base class and
|
||||
introduce it into the inheritance hierarchy *after* the defaults::
|
||||
|
||||
class ExtraManager(models.Model):
|
||||
extra_manager = OtherManager()
|
||||
@@ -431,8 +433,8 @@ is legal, but::
|
||||
will raise an exception. This is because managers are intended to encapsulate
|
||||
logic for managing collections of objects. Since you can't have a collection of
|
||||
abstract objects, it doesn't make sense to be managing them. If you have
|
||||
functionality that applies to the abstract model, you should put that functionality
|
||||
in a ``staticmethod`` or ``classmethod`` on the abstract model.
|
||||
functionality that applies to the abstract model, you should put that
|
||||
functionality in a ``staticmethod`` or ``classmethod`` on the abstract model.
|
||||
|
||||
Implementation concerns
|
||||
-----------------------
|
||||
|
||||
@@ -61,8 +61,8 @@ Some technical notes:
|
||||
Using models
|
||||
============
|
||||
|
||||
Once you have defined your models, you need to tell Django you're going to *use*
|
||||
those models. Do this by editing your settings file and changing the
|
||||
Once you have defined your models, you need to tell Django you're going to
|
||||
*use* those models. Do this by editing your settings file and changing the
|
||||
:setting:`INSTALLED_APPS` setting to add the name of the module that contains
|
||||
your ``models.py``.
|
||||
|
||||
@@ -117,15 +117,15 @@ determine a few things:
|
||||
* The column type, which tells the database what kind of data to store (e.g.
|
||||
``INTEGER``, ``VARCHAR``, ``TEXT``).
|
||||
|
||||
* The default HTML :doc:`widget </ref/forms/widgets>` to use when rendering a form
|
||||
field (e.g. ``<input type="text">``, ``<select>``).
|
||||
* The default HTML :doc:`widget </ref/forms/widgets>` to use when rendering a
|
||||
form field (e.g. ``<input type="text">``, ``<select>``).
|
||||
|
||||
* The minimal validation requirements, used in Django's admin and in
|
||||
automatically-generated forms.
|
||||
|
||||
Django ships with dozens of built-in field types; you can find the complete list
|
||||
in the :ref:`model field reference <model-field-types>`. You can easily write
|
||||
your own fields if Django's built-in ones don't do the trick; see
|
||||
Django ships with dozens of built-in field types; you can find the complete
|
||||
list in the :ref:`model field reference <model-field-types>`. You can easily
|
||||
write your own fields if Django's built-in ones don't do the trick; see
|
||||
:doc:`/howto/custom-model-fields`.
|
||||
|
||||
Field options
|
||||
@@ -134,13 +134,13 @@ Field options
|
||||
Each field takes a certain set of field-specific arguments (documented in the
|
||||
:ref:`model field reference <model-field-types>`). For example,
|
||||
:class:`~django.db.models.CharField` (and its subclasses) require a
|
||||
:attr:`~django.db.models.CharField.max_length` argument which specifies the size
|
||||
of the ``VARCHAR`` database field used to store the data.
|
||||
:attr:`~django.db.models.CharField.max_length` argument which specifies the
|
||||
size of the ``VARCHAR`` database field used to store the data.
|
||||
|
||||
There's also a set of common arguments available to all field types. All are
|
||||
optional. They're fully explained in the :ref:`reference
|
||||
<common-model-field-options>`, but here's a quick summary of the most often-used
|
||||
ones:
|
||||
<common-model-field-options>`, but here's a quick summary of the most
|
||||
often-used ones:
|
||||
|
||||
:attr:`~Field.null`
|
||||
If ``True``, Django will store empty values as ``NULL`` in the database.
|
||||
@@ -284,10 +284,9 @@ type specified per app in :attr:`AppConfig.default_auto_field
|
||||
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
|
||||
If you'd like to specify a custom primary key, specify
|
||||
:attr:`primary_key=True <Field.primary_key>` on one of your fields. If Django
|
||||
sees you've explicitly set :attr:`Field.primary_key`, it won't add the automatic
|
||||
``id`` column.
|
||||
If you'd like to specify a custom primary key, specify :attr:`primary_key=True
|
||||
<Field.primary_key>` on one of your fields. If Django sees you've explicitly
|
||||
set :attr:`Field.primary_key`, it won't add the automatic ``id`` column.
|
||||
|
||||
Each model requires exactly one field to have :attr:`primary_key=True
|
||||
<Field.primary_key>` (either explicitly declared or automatically added).
|
||||
@@ -301,8 +300,8 @@ Each field type, except for :class:`~django.db.models.ForeignKey`,
|
||||
:class:`~django.db.models.ManyToManyField` and
|
||||
:class:`~django.db.models.OneToOneField`, takes an optional first positional
|
||||
argument -- a verbose name. If the verbose name isn't given, Django will
|
||||
automatically create it using the field's attribute name, converting underscores
|
||||
to spaces.
|
||||
automatically create it using the field's attribute name, converting
|
||||
underscores to spaces.
|
||||
|
||||
In this example, the verbose name is ``"person's first name"``::
|
||||
|
||||
@@ -366,9 +365,9 @@ For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
|
||||
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
|
||||
# ...
|
||||
|
||||
You can also create :ref:`recursive relationships <recursive-relationships>` (an
|
||||
object with a many-to-one relationship to itself) and :ref:`relationships to
|
||||
models not yet defined <lazy-relationships>`; see :ref:`the model field
|
||||
You can also create :ref:`recursive relationships <recursive-relationships>`
|
||||
(an object with a many-to-one relationship to itself) and :ref:`relationships
|
||||
to models not yet defined <lazy-relationships>`; see :ref:`the model field
|
||||
reference <ref-foreignkey>` for details.
|
||||
|
||||
It's suggested, but not required, that the name of a
|
||||
@@ -390,8 +389,8 @@ want. For example::
|
||||
<foreign-key-arguments>`. These options help define how the relationship
|
||||
should work; all are optional.
|
||||
|
||||
For details on accessing backwards-related objects, see the
|
||||
:ref:`Following relationships backward example <backwards-related-objects>`.
|
||||
For details on accessing backwards-related objects, see the :ref:`Following
|
||||
relationships backward example <backwards-related-objects>`.
|
||||
|
||||
For sample code, see the :doc:`Many-to-one relationship model example
|
||||
</topics/db/examples/many_to_one>`.
|
||||
@@ -465,8 +464,8 @@ matching pizzas and toppings, a standard
|
||||
you may need to associate data with the relationship between two models.
|
||||
|
||||
For example, consider the case of an application tracking the musical groups
|
||||
which musicians belong to. There is a many-to-many relationship between a person
|
||||
and the groups of which they are a member, so you could use a
|
||||
which musicians belong to. There is a many-to-many relationship between a
|
||||
person and the groups of which they are a member, so you could use a
|
||||
:class:`~django.db.models.ManyToManyField` to represent this relationship.
|
||||
However, there is a lot of detail about the membership that you might want to
|
||||
collect, such as the date at which the person joined the group.
|
||||
@@ -524,11 +523,11 @@ There are a few restrictions on the intermediate model:
|
||||
* Your intermediate model must contain one - and *only* one - foreign key
|
||||
to the source model (this would be ``Group`` in our example), or you must
|
||||
explicitly specify the foreign keys Django should use for the relationship
|
||||
using :attr:`ManyToManyField.through_fields <ManyToManyField.through_fields>`.
|
||||
If you have more than one foreign key and ``through_fields`` is not
|
||||
specified, a validation error will be raised. A similar restriction applies
|
||||
to the foreign key to the target model (this would be ``Person`` in our
|
||||
example).
|
||||
using :attr:`ManyToManyField.through_fields
|
||||
<ManyToManyField.through_fields>`. If you have more than one foreign key and
|
||||
``through_fields`` is not specified, a validation error will be raised. A
|
||||
similar restriction applies to the foreign key to the target model (this
|
||||
would be ``Person`` in our example).
|
||||
|
||||
* For a model which has a many-to-many relationship to itself through an
|
||||
intermediary model, two foreign keys to the same model are permitted, but
|
||||
@@ -800,13 +799,13 @@ Give your model metadata by using an inner ``class Meta``, like so::
|
||||
verbose_name_plural = "oxen"
|
||||
|
||||
Model metadata is "anything that's not a field", such as ordering options
|
||||
(:attr:`~Options.ordering`), database table name (:attr:`~Options.db_table`), or
|
||||
human-readable singular and plural names (:attr:`~Options.verbose_name` and
|
||||
(:attr:`~Options.ordering`), database table name (:attr:`~Options.db_table`),
|
||||
or human-readable singular and plural names (:attr:`~Options.verbose_name` and
|
||||
:attr:`~Options.verbose_name_plural`). None are required, and adding ``class
|
||||
Meta`` to a model is completely optional.
|
||||
|
||||
A complete list of all possible ``Meta`` options can be found in the :doc:`model
|
||||
option reference </ref/models/options>`.
|
||||
A complete list of all possible ``Meta`` options can be found in the
|
||||
:doc:`model option reference </ref/models/options>`.
|
||||
|
||||
.. _model-attributes:
|
||||
|
||||
@@ -827,9 +826,10 @@ Model attributes
|
||||
Model methods
|
||||
=============
|
||||
|
||||
Define custom methods on a model to add custom "row-level" functionality to your
|
||||
objects. Whereas :class:`~django.db.models.Manager` methods are intended to do
|
||||
"table-wide" things, model methods should act on a particular model instance.
|
||||
Define custom methods on a model to add custom "row-level" functionality to
|
||||
your objects. Whereas :class:`~django.db.models.Manager` methods are intended
|
||||
to do "table-wide" things, model methods should act on a particular model
|
||||
instance.
|
||||
|
||||
This is a valuable technique for keeping business logic in one place -- the
|
||||
model.
|
||||
@@ -1059,11 +1059,12 @@ still only creating one database table per child model at the database level.
|
||||
``Meta`` inheritance
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When an abstract base class is created, Django makes any :ref:`Meta <meta-options>`
|
||||
inner class you declared in the base class available as an
|
||||
attribute. If a child class does not declare its own :ref:`Meta <meta-options>`
|
||||
class, it will inherit the parent's :ref:`Meta <meta-options>`. If the child wants to
|
||||
extend the parent's :ref:`Meta <meta-options>` class, it can subclass it. For example::
|
||||
When an abstract base class is created, Django makes any
|
||||
:ref:`Meta <meta-options>` inner class you declared in the base class available
|
||||
as an attribute. If a child class does not declare its own
|
||||
:ref:`Meta <meta-options>` class, it will inherit the parent's
|
||||
:ref:`Meta <meta-options>`. If the child wants to extend the parent's
|
||||
:ref:`Meta <meta-options>` class, it can subclass it. For example::
|
||||
|
||||
from django.db import models
|
||||
|
||||
@@ -1087,10 +1088,11 @@ base classes don't automatically become abstract classes themselves. To make
|
||||
an abstract base class that inherits from another abstract base class, you need
|
||||
to explicitly set ``abstract=True`` on the child.
|
||||
|
||||
Some attributes won't make sense to include in the :ref:`Meta <meta-options>` class of an
|
||||
abstract base class. For example, including ``db_table`` would mean that all
|
||||
the child classes (the ones that don't specify their own :ref:`Meta <meta-options>`) would use
|
||||
the same database table, which is almost certainly not what you want.
|
||||
Some attributes won't make sense to include in the :ref:`Meta <meta-options>`
|
||||
class of an abstract base class. For example, including ``db_table`` would mean
|
||||
that all the child classes (the ones that don't specify their own
|
||||
:ref:`Meta <meta-options>`) would use the same database table, which is almost
|
||||
certainly not what you want.
|
||||
|
||||
Due to the way Python inheritance works, if a child class inherits from
|
||||
multiple abstract base classes, only the :ref:`Meta <meta-options>` options
|
||||
@@ -1181,15 +1183,15 @@ Along with another app ``rare/models.py``::
|
||||
pass
|
||||
|
||||
The reverse name of the ``common.ChildA.m2m`` field will be
|
||||
``common_childa_related`` and the reverse query name will be ``common_childas``.
|
||||
The reverse name of the ``common.ChildB.m2m`` field will be
|
||||
``common_childa_related`` and the reverse query name will be
|
||||
``common_childas``. The reverse name of the ``common.ChildB.m2m`` field will be
|
||||
``common_childb_related`` and the reverse query name will be
|
||||
``common_childbs``. Finally, the reverse name of the ``rare.ChildB.m2m`` field
|
||||
will be ``rare_childb_related`` and the reverse query name will be
|
||||
``rare_childbs``. It's up to you how you use the ``'%(class)s'`` and
|
||||
``'%(app_label)s'`` portion to construct your related name or related query name
|
||||
but if you forget to use it, Django will raise errors when you perform system
|
||||
checks (or run :djadmin:`migrate`).
|
||||
``'%(app_label)s'`` portion to construct your related name or related query
|
||||
name but if you forget to use it, Django will raise errors when you perform
|
||||
system checks (or run :djadmin:`migrate`).
|
||||
|
||||
If you don't specify a :attr:`~django.db.models.ForeignKey.related_name`
|
||||
attribute for a field in an abstract base class, the default reverse name will
|
||||
@@ -1269,11 +1271,11 @@ You can override that field by declaring your own
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the multi-table inheritance situation, it doesn't make sense for a child
|
||||
class to inherit from its parent's :ref:`Meta <meta-options>` class. All the :ref:`Meta <meta-options>` options
|
||||
have already been applied to the parent class and applying them again would
|
||||
normally only lead to contradictory behavior (this is in contrast with the
|
||||
abstract base class case, where the base class doesn't exist in its own
|
||||
right).
|
||||
class to inherit from its parent's :ref:`Meta <meta-options>` class. All the
|
||||
:ref:`Meta <meta-options>` options have already been applied to the parent
|
||||
class and applying them again would normally only lead to contradictory
|
||||
behavior (this is in contrast with the abstract base class case, where the base
|
||||
class doesn't exist in its own right).
|
||||
|
||||
So a child model does not have access to its parent's :ref:`Meta
|
||||
<meta-options>` class. However, there are a few limited cases where the child
|
||||
@@ -1359,7 +1361,8 @@ Proxy models are declared like normal models. You tell Django that it's a
|
||||
proxy model by setting the :attr:`~django.db.models.Options.proxy` attribute of
|
||||
the ``Meta`` class to ``True``.
|
||||
|
||||
For example, suppose you want to add a method to the ``Person`` model. You can do it like this::
|
||||
For example, suppose you want to add a method to the ``Person`` model. You can
|
||||
do it like this::
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
@@ -587,7 +587,8 @@ solution is to use ``db_manager()``, like this::
|
||||
|
||||
User.objects.db_manager("new_users").create_user(...)
|
||||
|
||||
``db_manager()`` returns a copy of the manager bound to the database you specify.
|
||||
``db_manager()`` returns a copy of the manager bound to the database you
|
||||
specify.
|
||||
|
||||
Using ``get_queryset()`` with multiple databases
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -21,8 +21,8 @@ your requirements. Sometimes optimizing for one will be detrimental to the
|
||||
other, but sometimes they will help each other. Also, work that is done by the
|
||||
database process might not have the same cost (to you) as the same amount of
|
||||
work done in your Python process. It is up to you to decide what your
|
||||
priorities are, where the balance must lie, and profile all of these as required
|
||||
since this will depend on your application and server.
|
||||
priorities are, where the balance must lie, and profile all of these as
|
||||
required since this will depend on your application and server.
|
||||
|
||||
With everything that follows, remember to profile after every change to ensure
|
||||
that the change is a benefit, and a big enough benefit given the decrease in
|
||||
@@ -202,8 +202,8 @@ Retrieve everything at once if you know you will need it
|
||||
Hitting the database multiple times for different parts of a single 'set' of
|
||||
data that you will need all parts of is, in general, less efficient than
|
||||
retrieving it all in one query. This is particularly important if you have a
|
||||
query that is executed in a loop, and could therefore end up doing many database
|
||||
queries, when only one was needed. So:
|
||||
query that is executed in a loop, and could therefore end up doing many
|
||||
database queries, when only one was needed. So:
|
||||
|
||||
Use ``QuerySet.select_related()`` and ``prefetch_related()``
|
||||
------------------------------------------------------------
|
||||
@@ -332,9 +332,9 @@ anything driven from the normal database object :doc:`signals </ref/signals>`.
|
||||
Use foreign key values directly
|
||||
-------------------------------
|
||||
|
||||
If you only need a foreign key value, use the foreign key value that is already on
|
||||
the object you've got, rather than getting the whole related object and taking
|
||||
its primary key. i.e. do::
|
||||
If you only need a foreign key value, use the foreign key value that is already
|
||||
on the object you've got, rather than getting the whole related object and
|
||||
taking its primary key. i.e. do::
|
||||
|
||||
entry.blog_id
|
||||
|
||||
|
||||
@@ -518,8 +518,8 @@ probably use:
|
||||
case-insensitive versions called :lookup:`istartswith` and
|
||||
:lookup:`iendswith`.
|
||||
|
||||
Again, this only scratches the surface. A complete reference can be found in the
|
||||
:ref:`field lookup reference <field-lookups>`.
|
||||
Again, this only scratches the surface. A complete reference can be found in
|
||||
the :ref:`field lookup reference <field-lookups>`.
|
||||
|
||||
.. _lookups-that-span-relationships:
|
||||
|
||||
@@ -706,10 +706,10 @@ and use that ``F()`` object in the query:
|
||||
>>> from django.db.models import F
|
||||
>>> Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks"))
|
||||
|
||||
Django supports the use of addition, subtraction, multiplication,
|
||||
division, modulo, and power arithmetic with ``F()`` objects, both with constants
|
||||
and with other ``F()`` objects. To find all the blog entries with more than
|
||||
*twice* as many comments as pingbacks, we modify the query:
|
||||
Django supports the use of addition, subtraction, multiplication, division,
|
||||
modulo, and power arithmetic with ``F()`` objects, both with constants and with
|
||||
other ``F()`` objects. To find all the blog entries with more than *twice* as
|
||||
many comments as pingbacks, we modify the query:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -1370,7 +1370,8 @@ Complex lookups with ``Q`` objects
|
||||
|
||||
Keyword argument queries -- in :meth:`~django.db.models.query.QuerySet.filter`,
|
||||
etc. -- are "AND"ed together. If you need to execute more complex queries (for
|
||||
example, queries with ``OR`` statements), you can use :class:`Q objects <django.db.models.Q>`.
|
||||
example, queries with ``OR`` statements), you can use
|
||||
:class:`Q objects <django.db.models.Q>`.
|
||||
|
||||
A :class:`Q object <django.db.models.Q>` (``django.db.models.Q``) is an object
|
||||
used to encapsulate a collection of keyword arguments. These keyword arguments
|
||||
@@ -1688,9 +1689,9 @@ When you define a relationship in a model (i.e., a
|
||||
:class:`~django.db.models.ManyToManyField`), instances of that model will have
|
||||
a convenient API to access the related object(s).
|
||||
|
||||
Using the models at the top of this page, for example, an ``Entry`` object ``e``
|
||||
can get its associated ``Blog`` object by accessing the ``blog`` attribute:
|
||||
``e.blog``.
|
||||
Using the models at the top of this page, for example, an ``Entry`` object
|
||||
``e`` can get its associated ``Blog`` object by accessing the ``blog``
|
||||
attribute: ``e.blog``.
|
||||
|
||||
(Behind the scenes, this functionality is implemented by Python
|
||||
:doc:`descriptors <python:howto/descriptor>`. This shouldn't really matter to
|
||||
@@ -1805,9 +1806,9 @@ Using a custom reverse manager
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default the :class:`~django.db.models.fields.related.RelatedManager` used
|
||||
for reverse relations is a subclass of the :ref:`default manager <manager-names>`
|
||||
for that model. If you would like to specify a different manager for a given
|
||||
query you can use the following syntax::
|
||||
for reverse relations is a subclass of the :ref:`default manager
|
||||
<manager-names>` for that model. If you would like to specify a different
|
||||
manager for a given query you can use the following syntax::
|
||||
|
||||
from django.db import models
|
||||
|
||||
@@ -1941,9 +1942,9 @@ For example::
|
||||
ed.entry # Returns the related Entry object.
|
||||
|
||||
The difference comes in "reverse" queries. The related model in a one-to-one
|
||||
relationship also has access to a :class:`~django.db.models.Manager` object, but
|
||||
that :class:`~django.db.models.Manager` represents a single object, rather than
|
||||
a collection of objects::
|
||||
relationship also has access to a :class:`~django.db.models.Manager` object,
|
||||
but that :class:`~django.db.models.Manager` represents a single object, rather
|
||||
than a collection of objects::
|
||||
|
||||
e = Entry.objects.get(id=2)
|
||||
e.entrydetail # returns the related EntryDetail object
|
||||
|
||||
@@ -49,7 +49,8 @@ This method takes a raw SQL query, executes it, and returns a
|
||||
can be iterated over like a normal :class:`~django.db.models.query.QuerySet` to
|
||||
provide object instances.
|
||||
|
||||
This is best illustrated with an example. Suppose you have the following model::
|
||||
This is best illustrated with an example. Suppose you have the following
|
||||
model::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(...)
|
||||
@@ -93,13 +94,13 @@ make it very powerful.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you are performing queries on MySQL, note that MySQL's silent type coercion
|
||||
may cause unexpected results when mixing types. If you query on a string
|
||||
type column, but with an integer value, MySQL will coerce the types of all values
|
||||
in the table to an integer before performing the comparison. For example, if your
|
||||
table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``,
|
||||
both rows will match. To prevent this, perform the correct typecasting
|
||||
before using the value in a query.
|
||||
If you are performing queries on MySQL, note that MySQL's silent type
|
||||
coercion may cause unexpected results when mixing types. If you query on a
|
||||
string type column, but with an integer value, MySQL will coerce the types
|
||||
of all values in the table to an integer before performing the comparison.
|
||||
For example, if your table contains the values ``'abc'``, ``'def'`` and you
|
||||
query for ``WHERE mycolumn=0``, both rows will match. To prevent this,
|
||||
perform the correct typecasting before using the value in a query.
|
||||
|
||||
Mapping query fields to model fields
|
||||
------------------------------------
|
||||
@@ -302,8 +303,8 @@ For example::
|
||||
To protect against SQL injection, you must not include quotes around the ``%s``
|
||||
placeholders in the SQL string.
|
||||
|
||||
Note that if you want to include literal percent signs in the query, you have to
|
||||
double them in the case you are passing parameters::
|
||||
Note that if you want to include literal percent signs in the query, you have
|
||||
to double them in the case you are passing parameters::
|
||||
|
||||
cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")
|
||||
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' AND id = %s", [self.id])
|
||||
|
||||
@@ -21,10 +21,10 @@ the :attr:`~django.db.models.Options.db_tablespace` option inside the model's
|
||||
``class Meta``. This option also affects tables automatically created for
|
||||
:class:`~django.db.models.ManyToManyField`\ s in the model.
|
||||
|
||||
You can use the :setting:`DEFAULT_TABLESPACE` setting to specify a default value
|
||||
for :attr:`~django.db.models.Options.db_tablespace`. This is useful for setting
|
||||
a tablespace for the built-in Django apps and other applications whose code you
|
||||
cannot control.
|
||||
You can use the :setting:`DEFAULT_TABLESPACE` setting to specify a default
|
||||
value for :attr:`~django.db.models.Options.db_tablespace`. This is useful for
|
||||
setting a tablespace for the built-in Django apps and other applications whose
|
||||
code you cannot control.
|
||||
|
||||
Declaring tablespaces for indexes
|
||||
=================================
|
||||
|
||||
@@ -45,10 +45,10 @@ either all or none of the changes will be committed.
|
||||
|
||||
.. warning::
|
||||
|
||||
While the simplicity of this transaction model is appealing, it also makes it
|
||||
inefficient when traffic increases. Opening a transaction for every view has
|
||||
some overhead. The impact on performance depends on the query patterns of your
|
||||
application and on how well your database handles locking.
|
||||
While the simplicity of this transaction model is appealing, it also makes
|
||||
it inefficient when traffic increases. Opening a transaction for every view
|
||||
has some overhead. The impact on performance depends on the query patterns
|
||||
of your application and on how well your database handles locking.
|
||||
|
||||
.. admonition:: Per-request transactions and streaming responses
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ if used.
|
||||
If unspecified, an instance of the default backend will be used.
|
||||
See the documentation on :ref:`Email backends <topic-email-backends>`
|
||||
for more details.
|
||||
* ``html_message``: If ``html_message`` is provided, the resulting email will be a
|
||||
:mimetype:`multipart/alternative` email with ``message`` as the
|
||||
* ``html_message``: If ``html_message`` is provided, the resulting email will
|
||||
be a :mimetype:`multipart/alternative` email with ``message`` as the
|
||||
:mimetype:`text/plain` content type and ``html_message`` as the
|
||||
:mimetype:`text/html` content type.
|
||||
|
||||
@@ -535,8 +535,8 @@ Django's email library, you can do this using the
|
||||
|
||||
.. attribute:: alternatives
|
||||
|
||||
A list of :class:`~django.core.mail.EmailAlternative` named tuples. This
|
||||
is particularly useful in tests::
|
||||
A list of :class:`~django.core.mail.EmailAlternative` named tuples.
|
||||
This is particularly useful in tests::
|
||||
|
||||
self.assertEqual(len(msg.alternatives), 1)
|
||||
self.assertEqual(msg.alternatives[0].content, html_content)
|
||||
|
||||
@@ -8,8 +8,8 @@ them for other purposes. If you want to handle "static files" (JS, CSS, etc.),
|
||||
see :doc:`/howto/static-files/index`.
|
||||
|
||||
By default, Django stores files locally, using the :setting:`MEDIA_ROOT` and
|
||||
:setting:`MEDIA_URL` settings. The examples below assume that you're using these
|
||||
defaults.
|
||||
:setting:`MEDIA_URL` settings. The examples below assume that you're using
|
||||
these defaults.
|
||||
|
||||
However, Django provides ways to write custom `file storage systems`_ that
|
||||
allow you to completely customize where and how Django stores files. The
|
||||
@@ -21,8 +21,8 @@ Using files in models
|
||||
=====================
|
||||
|
||||
When you use a :class:`~django.db.models.FileField` or
|
||||
:class:`~django.db.models.ImageField`, Django provides a set of APIs you can use
|
||||
to deal with that file.
|
||||
:class:`~django.db.models.ImageField`, Django provides a set of APIs you can
|
||||
use to deal with that file.
|
||||
|
||||
Consider the following model, using an :class:`~django.db.models.ImageField` to
|
||||
store a photo::
|
||||
@@ -51,13 +51,13 @@ the details of the attached photo:
|
||||
>>> car.photo.url
|
||||
'https://media.example.com/cars/chevy.jpg'
|
||||
|
||||
This object -- ``car.photo`` in the example -- is a ``File`` object, which means
|
||||
it has all the methods and attributes described below.
|
||||
This object -- ``car.photo`` in the example -- is a ``File`` object, which
|
||||
means it has all the methods and attributes described below.
|
||||
|
||||
.. note::
|
||||
The file is saved as part of saving the model in the database, so the actual
|
||||
file name used on disk cannot be relied on until after the model has been
|
||||
saved.
|
||||
The file is saved as part of saving the model in the database, so the
|
||||
actual file name used on disk cannot be relied on until after the model has
|
||||
been saved.
|
||||
|
||||
For example, you can change the file name by setting the file's
|
||||
:attr:`~django.core.files.File.name` to a path relative to the file storage's
|
||||
@@ -168,9 +168,9 @@ may lead to the following error:
|
||||
File storage
|
||||
============
|
||||
|
||||
Behind the scenes, Django delegates decisions about how and where to store files
|
||||
to a file storage system. This is the object that actually understands things
|
||||
like file systems, opening and reading files, etc.
|
||||
Behind the scenes, Django delegates decisions about how and where to store
|
||||
files to a file storage system. This is the object that actually understands
|
||||
things like file systems, opening and reading files, etc.
|
||||
|
||||
Django's default file storage is
|
||||
``'``:class:`django.core.files.storage.FileSystemStorage`\ ``'``. If you don't
|
||||
@@ -184,10 +184,10 @@ storage system.
|
||||
Storage objects
|
||||
---------------
|
||||
|
||||
Though most of the time you'll want to use a ``File`` object (which delegates to
|
||||
the proper storage for that file), you can use file storage systems directly.
|
||||
You can create an instance of some custom file storage class, or -- often more
|
||||
useful -- you can use the global default storage system:
|
||||
Though most of the time you'll want to use a ``File`` object (which delegates
|
||||
to the proper storage for that file), you can use file storage systems
|
||||
directly. You can create an instance of some custom file storage class, or --
|
||||
often more useful -- you can use the global default storage system:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
||||
@@ -274,12 +274,13 @@ provide this management data, the formset will be invalid:
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
|
||||
It is used to keep track of how many form instances are being displayed. If
|
||||
you are adding new forms via JavaScript, you should increment the count fields
|
||||
in this form as well. On the other hand, if you are using JavaScript to allow
|
||||
It is used to keep track of how many form instances are being displayed. If you
|
||||
are adding new forms via JavaScript, you should increment the count fields in
|
||||
this form as well. On the other hand, if you are using JavaScript to allow
|
||||
deletion of existing objects, then you need to ensure the ones being removed
|
||||
are properly marked for deletion by including ``form-#-DELETE`` in the ``POST``
|
||||
data. It is expected that all forms are present in the ``POST`` data regardless.
|
||||
data. It is expected that all forms are present in the ``POST`` data
|
||||
regardless.
|
||||
|
||||
The management form is available as an attribute of the formset
|
||||
itself. When rendering a formset in a template, you can include all
|
||||
|
||||
@@ -192,9 +192,9 @@ the user's name. You'd need something like this in your template:
|
||||
<input type="submit" value="OK">
|
||||
</form>
|
||||
|
||||
This tells the browser to return the form data to the URL ``/your-name/``, using
|
||||
the ``POST`` method. It will display a text field, labeled "Your name:", and a
|
||||
button marked "OK". If the template context contains a ``current_name``
|
||||
This tells the browser to return the form data to the URL ``/your-name/``,
|
||||
using the ``POST`` method. It will display a text field, labeled "Your name:",
|
||||
and a button marked "OK". If the template context contains a ``current_name``
|
||||
variable, that will be used to pre-fill the ``your_name`` field.
|
||||
|
||||
You'll need a view that renders the template containing the HTML form, and
|
||||
@@ -203,8 +203,9 @@ that can supply the ``current_name`` field as appropriate.
|
||||
When the form is submitted, the ``POST`` request which is sent to the server
|
||||
will contain the form data.
|
||||
|
||||
Now you'll also need a view corresponding to that ``/your-name/`` URL which will
|
||||
find the appropriate key/value pairs in the request, and then process them.
|
||||
Now you'll also need a view corresponding to that ``/your-name/`` URL which
|
||||
will find the appropriate key/value pairs in the request, and then process
|
||||
them.
|
||||
|
||||
This is a very simple form. In practice, a form might contain dozens or
|
||||
hundreds of fields, many of which might need to be prepopulated, and we might
|
||||
@@ -343,12 +344,12 @@ from that ``{{ form }}`` by Django's template language.
|
||||
|
||||
.. admonition:: Forms and Cross Site Request Forgery protection
|
||||
|
||||
Django ships with an easy-to-use :doc:`protection against Cross Site Request
|
||||
Forgeries </ref/csrf>`. When submitting a form via ``POST`` with
|
||||
CSRF protection enabled you must use the :ttag:`csrf_token` template tag
|
||||
as in the preceding example. However, since CSRF protection is not
|
||||
directly tied to forms in templates, this tag is omitted from the
|
||||
following examples in this document.
|
||||
Django ships with an easy-to-use :doc:`protection against Cross Site
|
||||
Request Forgeries </ref/csrf>`. When submitting a form via ``POST`` with
|
||||
CSRF protection enabled you must use the :ttag:`csrf_token` template tag as
|
||||
in the preceding example. However, since CSRF protection is not directly
|
||||
tied to forms in templates, this tag is omitted from the following examples
|
||||
in this document.
|
||||
|
||||
.. admonition:: HTML5 input types and browser validation
|
||||
|
||||
@@ -381,8 +382,8 @@ detail is rarely important.
|
||||
|
||||
In fact if your form is going to be used to directly add or edit a Django
|
||||
model, a :doc:`ModelForm </topics/forms/modelforms>` can save you a great
|
||||
deal of time, effort, and code, because it will build a form, along with the
|
||||
appropriate fields and their attributes, from a ``Model`` class.
|
||||
deal of time, effort, and code, because it will build a form, along with
|
||||
the appropriate fields and their attributes, from a ``Model`` class.
|
||||
|
||||
Bound and unbound form instances
|
||||
--------------------------------
|
||||
|
||||
@@ -117,7 +117,8 @@ requirements::
|
||||
"print": ["newspaper.css"],
|
||||
}
|
||||
|
||||
If this last CSS definition were to be rendered, it would become the following HTML:
|
||||
If this last CSS definition were to be rendered, it would become the following
|
||||
HTML:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
|
||||
@@ -311,7 +311,8 @@ the form level.
|
||||
|
||||
You can override the error messages from ``NON_FIELD_ERRORS`` raised by model
|
||||
validation by adding the :data:`~django.core.exceptions.NON_FIELD_ERRORS` key
|
||||
to the ``error_messages`` dictionary of the ``ModelForm``’s inner ``Meta`` class::
|
||||
to the ``error_messages`` dictionary of the ``ModelForm``’s inner ``Meta``
|
||||
class::
|
||||
|
||||
from django.core.exceptions import NON_FIELD_ERRORS
|
||||
from django.forms import ModelForm
|
||||
@@ -440,9 +441,10 @@ fields, especially when new fields are added to a model. Depending on how the
|
||||
form is rendered, the problem may not even be visible on the web page.
|
||||
|
||||
The alternative approach would be to include all fields automatically, or
|
||||
remove only some. This fundamental approach is known to be much less secure
|
||||
and has led to serious exploits on major websites (e.g. `GitHub
|
||||
<https://github.blog/2012-03-04-public-key-security-vulnerability-and-mitigation/>`_).
|
||||
remove only some. This fundamental approach is known to be much less secure and
|
||||
has led to serious exploits on major websites (e.g. `GitHub
|
||||
<https://github.blog/2012-03-04-public-key-security-vulnerability-and-mitigation/>`__
|
||||
).
|
||||
|
||||
There are, however, two shortcuts available for cases where you can guarantee
|
||||
these security concerns do not apply to you:
|
||||
@@ -472,13 +474,13 @@ these security concerns do not apply to you:
|
||||
``birth_date``, this will result in the fields ``name`` and ``birth_date``
|
||||
being present on the form.
|
||||
|
||||
If either of these are used, the order the fields appear in the form will be the
|
||||
order the fields are defined in the model, with ``ManyToManyField`` instances
|
||||
appearing last.
|
||||
If either of these are used, the order the fields appear in the form will be
|
||||
the order the fields are defined in the model, with ``ManyToManyField``
|
||||
instances appearing last.
|
||||
|
||||
In addition, Django applies the following rule: if you set ``editable=False`` on
|
||||
the model field, *any* form created from the model via ``ModelForm`` will not
|
||||
include that field.
|
||||
In addition, Django applies the following rule: if you set ``editable=False``
|
||||
on the model field, *any* form created from the model via ``ModelForm`` will
|
||||
not include that field.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -546,11 +548,12 @@ The ``widgets`` dictionary accepts either widget instances (e.g.,
|
||||
dictionary is ignored for a model field with a non-empty ``choices`` attribute.
|
||||
In this case, you must override the form field to use a different widget.
|
||||
|
||||
Similarly, you can specify the ``labels``, ``help_texts`` and ``error_messages``
|
||||
attributes of the inner ``Meta`` class if you want to further customize a field.
|
||||
Similarly, you can specify the ``labels``, ``help_texts`` and
|
||||
``error_messages`` attributes of the inner ``Meta`` class if you want to
|
||||
further customize a field.
|
||||
|
||||
For example if you wanted to customize the wording of all user facing strings for
|
||||
the ``name`` field::
|
||||
For example if you wanted to customize the wording of all user facing strings
|
||||
for the ``name`` field::
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@@ -633,14 +636,14 @@ the field declaratively and setting its ``validators`` parameter::
|
||||
``ModelForm`` is a regular ``Form`` which can automatically generate
|
||||
certain fields. The fields that are automatically generated depend on
|
||||
the content of the ``Meta`` class and on which fields have already been
|
||||
defined declaratively. Basically, ``ModelForm`` will **only** generate fields
|
||||
that are **missing** from the form, or in other words, fields that weren't
|
||||
defined declaratively.
|
||||
defined declaratively. Basically, ``ModelForm`` will **only** generate
|
||||
fields that are **missing** from the form, or in other words, fields that
|
||||
weren't defined declaratively.
|
||||
|
||||
Fields defined declaratively are left as-is, therefore any customizations
|
||||
made to ``Meta`` attributes such as ``widgets``, ``labels``, ``help_texts``,
|
||||
or ``error_messages`` are ignored; these only apply to fields that are
|
||||
generated automatically.
|
||||
made to ``Meta`` attributes such as ``widgets``, ``labels``,
|
||||
``help_texts``, or ``error_messages`` are ignored; these only apply to
|
||||
fields that are generated automatically.
|
||||
|
||||
Similarly, fields defined declaratively do not draw their attributes like
|
||||
``max_length`` or ``required`` from the corresponding model. If you want to
|
||||
@@ -677,8 +680,8 @@ the field declaratively and setting its ``validators`` parameter::
|
||||
contents of the corresponding model field. When they are not compatible,
|
||||
you will get a ``ValueError`` as no implicit conversion takes place.
|
||||
|
||||
See the :doc:`form field documentation </ref/forms/fields>` for more information
|
||||
on fields and their arguments.
|
||||
See the :doc:`form field documentation </ref/forms/fields>` for more
|
||||
information on fields and their arguments.
|
||||
|
||||
Enabling localization of fields
|
||||
-------------------------------
|
||||
@@ -739,12 +742,12 @@ There are a couple of things to note, however.
|
||||
because these classes rely on different metaclasses and a class can only have
|
||||
one metaclass.
|
||||
|
||||
* It's possible to declaratively remove a ``Field`` inherited from a parent class by
|
||||
setting the name to be ``None`` on the subclass.
|
||||
* It's possible to declaratively remove a ``Field`` inherited from a parent
|
||||
class by setting the name to be ``None`` on the subclass.
|
||||
|
||||
You can only use this technique to opt out from a field defined declaratively
|
||||
by a parent class; it won't prevent the ``ModelForm`` metaclass from generating
|
||||
a default field. To opt-out from default fields, see
|
||||
by a parent class; it won't prevent the ``ModelForm`` metaclass from
|
||||
generating a default field. To opt-out from default fields, see
|
||||
:ref:`modelforms-selecting-fields`.
|
||||
|
||||
Providing initial values
|
||||
@@ -1279,7 +1282,8 @@ a particular author, you could do this:
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`Manually rendered can_delete and can_order <manually-rendered-can-delete-and-can-order>`.
|
||||
:ref:`Manually rendered can_delete and can_order
|
||||
<manually-rendered-can-delete-and-can-order>`.
|
||||
|
||||
Overriding methods on an ``InlineFormSet``
|
||||
------------------------------------------
|
||||
|
||||
@@ -102,8 +102,8 @@ caching based on specific request headers.
|
||||
|
||||
.. function:: vary_on_headers(*headers)
|
||||
|
||||
The ``Vary`` header defines which request headers a cache mechanism should take
|
||||
into account when building its cache key.
|
||||
The ``Vary`` header defines which request headers a cache mechanism should
|
||||
take into account when building its cache key.
|
||||
|
||||
See :ref:`using vary headers <using-vary-headers>`.
|
||||
|
||||
|
||||
@@ -67,8 +67,9 @@ described in :ref:`binding-uploaded-files`. This would look something like:
|
||||
form = UploadFileForm()
|
||||
return render(request, "upload.html", {"form": form})
|
||||
|
||||
Notice that we have to pass :attr:`request.FILES <django.http.HttpRequest.FILES>`
|
||||
into the form's constructor; this is how file data gets bound into a form.
|
||||
Notice that we have to pass :attr:`request.FILES
|
||||
<django.http.HttpRequest.FILES>` into the form's constructor; this is how file
|
||||
data gets bound into a form.
|
||||
|
||||
Here's a common way you might handle an uploaded file::
|
||||
|
||||
@@ -259,8 +260,8 @@ involves only a read from memory and a write to disk and thus is very fast.
|
||||
However, if an uploaded file is too large, Django will write the uploaded file
|
||||
to a temporary file stored in your system's temporary directory. On a Unix-like
|
||||
platform this means you can expect Django to generate a file called something
|
||||
like ``/tmp/tmpzfp6I6.upload``. If an upload is large enough, you can watch this
|
||||
file grow in size as Django streams the data onto disk.
|
||||
like ``/tmp/tmpzfp6I6.upload``. If an upload is large enough, you can watch
|
||||
this file grow in size as Django streams the data onto disk.
|
||||
|
||||
These specifics -- 2.5 megabytes; ``/tmp``; etc. -- are "reasonable defaults"
|
||||
which can be customized as described in the next section.
|
||||
@@ -283,8 +284,8 @@ handlers given by :setting:`FILE_UPLOAD_HANDLERS`, but you can modify the list
|
||||
as you would any other list.
|
||||
|
||||
For instance, suppose you've written a ``ProgressBarUploadHandler`` that
|
||||
provides feedback on upload progress to some sort of AJAX widget. You'd add this
|
||||
handler to your upload handlers like this::
|
||||
provides feedback on upload progress to some sort of AJAX widget. You'd add
|
||||
this handler to your upload handlers like this::
|
||||
|
||||
request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
|
||||
|
||||
|
||||
@@ -131,10 +131,10 @@ and the :setting:`SECRET_KEY` setting.
|
||||
When using the cookies backend the session data can be read by the client.
|
||||
|
||||
A MAC (Message Authentication Code) is used to protect the data against
|
||||
changes by the client, so that the session data will be invalidated when being
|
||||
tampered with. The same invalidation happens if the client storing the
|
||||
cookie (e.g. your user's browser) can't store all of the session cookie and
|
||||
drops data. Even though Django compresses the data, it's still entirely
|
||||
changes by the client, so that the session data will be invalidated when
|
||||
being tampered with. The same invalidation happens if the client storing
|
||||
the cookie (e.g. your user's browser) can't store all of the session cookie
|
||||
and drops data. Even though Django compresses the data, it's still entirely
|
||||
possible to exceed the :rfc:`common limit of 4096 bytes <2965#section-5.3>`
|
||||
per cookie.
|
||||
|
||||
@@ -578,8 +578,8 @@ calls ``save()`` and loops until an unused ``session_key`` is generated.
|
||||
|
||||
If you're using the ``django.contrib.sessions.backends.db`` backend, each
|
||||
session is a normal Django model. The ``Session`` model is defined in
|
||||
:source:`django/contrib/sessions/models.py`. Because it's a normal model, you can
|
||||
access sessions using the normal Django database API:
|
||||
:source:`django/contrib/sessions/models.py`. Because it's a normal model, you
|
||||
can access sessions using the normal Django database API:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -728,11 +728,12 @@ domain. This makes session fixation possible if cookies are permitted from
|
||||
subdomains not controlled by trusted users.
|
||||
|
||||
For example, an attacker could log into ``good.example.com`` and get a valid
|
||||
session for their account. If the attacker has control over ``bad.example.com``,
|
||||
they can use it to send their session key to you since a subdomain is permitted
|
||||
to set cookies on ``*.example.com``. When you visit ``good.example.com``,
|
||||
you'll be logged in as the attacker and might inadvertently enter your
|
||||
sensitive personal data (e.g. credit card info) into the attacker's account.
|
||||
session for their account. If the attacker has control over
|
||||
``bad.example.com``, they can use it to send their session key to you since a
|
||||
subdomain is permitted to set cookies on ``*.example.com``. When you visit
|
||||
``good.example.com``, you'll be logged in as the attacker and might
|
||||
inadvertently enter your sensitive personal data (e.g. credit card info) into
|
||||
the attacker's account.
|
||||
|
||||
Another possible attack would be if ``good.example.com`` sets its
|
||||
:setting:`SESSION_COOKIE_DOMAIN` to ``"example.com"`` which would cause
|
||||
@@ -839,7 +840,8 @@ You can also customize the model manager by subclassing
|
||||
|
||||
.. method:: encode(session_dict)
|
||||
|
||||
Returns the given session dictionary serialized and encoded as a string.
|
||||
Returns the given session dictionary serialized and encoded as a
|
||||
string.
|
||||
|
||||
Encoding is performed by the session store class tied to a model class.
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ How Django processes a request
|
||||
When a user requests a page from your Django-powered site, this is the
|
||||
algorithm the system follows to determine which Python code to execute:
|
||||
|
||||
#. Django determines the root URLconf module to use. Ordinarily,
|
||||
this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
|
||||
#. Django determines the root URLconf module to use. Ordinarily, this is the
|
||||
value of the :setting:`ROOT_URLCONF` setting, but if the incoming
|
||||
``HttpRequest`` object has a :attr:`~django.http.HttpRequest.urlconf`
|
||||
attribute (set by middleware), its value will be used in place of the
|
||||
:setting:`ROOT_URLCONF` setting.
|
||||
@@ -86,8 +86,8 @@ Notes:
|
||||
* To capture a value from the URL, use angle brackets.
|
||||
|
||||
* Captured values can optionally include a converter type. For example, use
|
||||
``<int:name>`` to capture an integer parameter. If a converter isn't included,
|
||||
any string, excluding a ``/`` character, is matched.
|
||||
``<int:name>`` to capture an integer parameter. If a converter isn't
|
||||
included, any string, excluding a ``/`` character, is matched.
|
||||
|
||||
* There's no need to add a leading slash, because every URL has that. For
|
||||
example, it's ``articles``, not ``/articles``.
|
||||
@@ -107,8 +107,8 @@ Example requests:
|
||||
* ``/articles/2003`` would not match any of these patterns, because each
|
||||
pattern requires that the URL end with a slash.
|
||||
|
||||
* ``/articles/2003/03/building-a-django-site/`` would match the final
|
||||
pattern. Django would call the function
|
||||
* ``/articles/2003/03/building-a-django-site/`` would match the final pattern.
|
||||
Django would call the function
|
||||
``views.article_detail(request, year=2003, month=3, slug="building-a-django-site")``.
|
||||
|
||||
Path converters
|
||||
@@ -116,8 +116,8 @@ Path converters
|
||||
|
||||
The following path converters are available by default:
|
||||
|
||||
* ``str`` - Matches any non-empty string, excluding the path separator, ``'/'``.
|
||||
This is the default if a converter isn't included in the expression.
|
||||
* ``str`` - Matches any non-empty string, excluding the path separator,
|
||||
``'/'``. This is the default if a converter isn't included in the expression.
|
||||
|
||||
* ``int`` - Matches zero or any positive integer. Returns an ``int``.
|
||||
|
||||
@@ -139,7 +139,8 @@ The following path converters are available by default:
|
||||
Registering custom path converters
|
||||
==================================
|
||||
|
||||
For more complex matching requirements, you can define your own path converters.
|
||||
For more complex matching requirements, you can define your own path
|
||||
converters.
|
||||
|
||||
A converter is a class that includes the following:
|
||||
|
||||
@@ -260,9 +261,9 @@ positional arguments: ``page-2/`` and ``2``. The second pattern for
|
||||
``page_number`` set to 2. The outer argument in this case is a non-capturing
|
||||
argument ``(?:...)``.
|
||||
|
||||
The ``blog_articles`` view needs the outermost captured argument to be reversed,
|
||||
``page-2/`` or no arguments in this case, while ``comments`` can be reversed
|
||||
with either no arguments or a value for ``page_number``.
|
||||
The ``blog_articles`` view needs the outermost captured argument to be
|
||||
reversed, ``page-2/`` or no arguments in this case, while ``comments`` can be
|
||||
reversed with either no arguments or a value for ``page_number``.
|
||||
|
||||
Nested captured arguments create a strong coupling between the view arguments
|
||||
and the URL as illustrated by ``blog_articles``: the view receives part of the
|
||||
@@ -283,8 +284,8 @@ does not include GET or POST parameters, or the domain name.
|
||||
For example, in a request to ``https://www.example.com/myapp/``, the URLconf
|
||||
will look for ``myapp/``.
|
||||
|
||||
In a request to ``https://www.example.com/myapp/?page=3``, the URLconf will look
|
||||
for ``myapp/``.
|
||||
In a request to ``https://www.example.com/myapp/?page=3``, the URLconf will
|
||||
look for ``myapp/``.
|
||||
|
||||
The URLconf doesn't look at the request method. In other words, all request
|
||||
methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same
|
||||
@@ -551,15 +552,16 @@ every view in the included URLconf accepts the extra options you're passing.
|
||||
Reverse resolution of URLs
|
||||
==========================
|
||||
|
||||
A common need when working on a Django project is the possibility to obtain URLs
|
||||
in their final forms either for embedding in generated content (views and assets
|
||||
URLs, URLs shown to the user, etc.) or for handling of the navigation flow on
|
||||
the server side (redirections, etc.)
|
||||
A common need when working on a Django project is the possibility to obtain
|
||||
URLs in their final forms either for embedding in generated content (views and
|
||||
assets URLs, URLs shown to the user, etc.) or for handling of the navigation
|
||||
flow on the server side (redirections, etc.)
|
||||
|
||||
It is strongly desirable to avoid hardcoding these URLs (a laborious,
|
||||
non-scalable and error-prone strategy). Equally dangerous is devising ad-hoc
|
||||
mechanisms to generate URLs that are parallel to the design described by the
|
||||
URLconf, which can result in the production of URLs that become stale over time.
|
||||
URLconf, which can result in the production of URLs that become stale over
|
||||
time.
|
||||
|
||||
In other words, what's needed is a DRY mechanism. Among other advantages it
|
||||
would allow evolution of the URL design without having to go over all the
|
||||
@@ -575,8 +577,8 @@ the URL design. You feed it with your URLconf and then it can be used in both
|
||||
directions:
|
||||
|
||||
* Starting with a URL requested by the user/browser, it calls the right Django
|
||||
view providing any arguments it might need with their values as extracted from
|
||||
the URL.
|
||||
view providing any arguments it might need with their values as extracted
|
||||
from the URL.
|
||||
|
||||
* Starting with the identification of the corresponding Django view plus the
|
||||
values of arguments that would be passed to it, obtain the associated URL.
|
||||
@@ -643,8 +645,8 @@ change the entry in the URLconf.
|
||||
|
||||
In some scenarios where views are of a generic nature, a many-to-one
|
||||
relationship might exist between URLs and views. For these cases the view name
|
||||
isn't a good enough identifier for it when comes the time of reversing
|
||||
URLs. Read the next section to know about the solution Django provides for this.
|
||||
isn't a good enough identifier for it when comes the time of reversing URLs.
|
||||
Read the next section to know about the solution Django provides for this.
|
||||
|
||||
.. _naming-url-patterns:
|
||||
|
||||
@@ -726,8 +728,8 @@ index page of the admin application is referenced using ``'admin:index'``. This
|
||||
indicates a namespace of ``'admin'``, and a named URL of ``'index'``.
|
||||
|
||||
Namespaces can also be nested. The named URL ``'sports:polls:index'`` would
|
||||
look for a pattern named ``'index'`` in the namespace ``'polls'`` that is itself
|
||||
defined within the top-level namespace ``'sports'``.
|
||||
look for a pattern named ``'index'`` in the namespace ``'polls'`` that is
|
||||
itself defined within the top-level namespace ``'sports'``.
|
||||
|
||||
.. _topics-http-reversing-url-namespaces:
|
||||
|
||||
@@ -771,11 +773,11 @@ resolved into a URL in the namespace that has been found.
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
To show this resolution strategy in action, consider an example of two instances
|
||||
of the ``polls`` application from the tutorial: one called ``'author-polls'``
|
||||
and one called ``'publisher-polls'``. Assume we have enhanced that application
|
||||
so that it takes the instance namespace into consideration when creating and
|
||||
displaying polls.
|
||||
To show this resolution strategy in action, consider an example of two
|
||||
instances of the ``polls`` application from the tutorial: one called
|
||||
``'author-polls'`` and one called ``'publisher-polls'``. Assume we have
|
||||
enhanced that application so that it takes the instance namespace into
|
||||
consideration when creating and displaying polls.
|
||||
|
||||
.. code-block:: python
|
||||
:caption: ``urls.py``
|
||||
@@ -803,10 +805,10 @@ displaying polls.
|
||||
|
||||
Using this setup, the following lookups are possible:
|
||||
|
||||
* If one of the instances is current - say, if we were rendering the detail page
|
||||
in the instance ``'author-polls'`` - ``'polls:index'`` will resolve to the
|
||||
index page of the ``'author-polls'`` instance; i.e. both of the following will
|
||||
result in ``"/author-polls/"``.
|
||||
* If one of the instances is current - say, if we were rendering the detail
|
||||
page in the instance ``'author-polls'`` - ``'polls:index'`` will resolve to
|
||||
the index page of the ``'author-polls'`` instance; i.e. both of the following
|
||||
will result in ``"/author-polls/"``.
|
||||
|
||||
In the method of a class-based view::
|
||||
|
||||
@@ -825,8 +827,8 @@ Using this setup, the following lookups are possible:
|
||||
registered will be used. This would be ``'publisher-polls'`` since it's
|
||||
declared last in the ``urlpatterns``.
|
||||
|
||||
* ``'author-polls:index'`` will always resolve to the index page of the instance
|
||||
``'author-polls'`` (and likewise for ``'publisher-polls'``) .
|
||||
* ``'author-polls:index'`` will always resolve to the index page of the
|
||||
instance ``'author-polls'`` (and likewise for ``'publisher-polls'``).
|
||||
|
||||
If there were also a default instance - i.e., an instance named ``'polls'`` -
|
||||
the only change from above would be in the case where there is no current
|
||||
@@ -869,7 +871,8 @@ not the list of ``urlpatterns`` itself.
|
||||
path("polls/", include("polls.urls")),
|
||||
]
|
||||
|
||||
The URLs defined in ``polls.urls`` will have an application namespace ``polls``.
|
||||
The URLs defined in ``polls.urls`` will have an application namespace
|
||||
``polls``.
|
||||
|
||||
Secondly, you can include an object that contains embedded namespace data. If
|
||||
you ``include()`` a list of :func:`~django.urls.path` or
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
Writing views
|
||||
=============
|
||||
|
||||
A view function, or *view* for short, is a Python function that takes a
|
||||
web request and returns a web response. This response can be the HTML contents
|
||||
of a web page, or a redirect, or a 404 error, or an XML document, or an image .
|
||||
. . or anything, really. The view itself contains whatever arbitrary logic is
|
||||
necessary to return that response. This code can live anywhere you want, as long
|
||||
as it's on your Python path. There's no other requirement--no "magic," so to
|
||||
speak. For the sake of putting the code *somewhere*, the convention is to
|
||||
put views in a file called ``views.py``, placed in your project or
|
||||
application directory.
|
||||
A view function, or *view* for short, is a Python function that takes a web
|
||||
request and returns a web response. This response can be the HTML contents of a
|
||||
web page, or a redirect, or a 404 error, or an XML document, or an image . . .
|
||||
or anything, really. The view itself contains whatever arbitrary logic is
|
||||
necessary to return that response. This code can live anywhere you want, as
|
||||
long as it's on your Python path. There's no other requirement--no "magic," so
|
||||
to speak. For the sake of putting the code *somewhere*, the convention is to
|
||||
put views in a file called ``views.py``, placed in your project or application
|
||||
directory.
|
||||
|
||||
A simple view
|
||||
=============
|
||||
@@ -55,8 +55,8 @@ Mapping URLs to views
|
||||
=====================
|
||||
|
||||
So, to recap, this view function returns an HTML page that includes the current
|
||||
date and time. To display this view at a particular URL, you'll need to create a
|
||||
*URLconf*; see :doc:`/topics/http/urls` for instructions.
|
||||
date and time. To display this view at a particular URL, you'll need to create
|
||||
a *URLconf*; see :doc:`/topics/http/urls` for instructions.
|
||||
|
||||
Returning errors
|
||||
================
|
||||
@@ -107,10 +107,11 @@ you're responsible for defining the HTML of the resulting error page::
|
||||
|
||||
return HttpResponseNotFound("<h1>Page not found</h1>")
|
||||
|
||||
For convenience, and because it's a good idea to have a consistent 404 error page
|
||||
across your site, Django provides an ``Http404`` exception. If you raise
|
||||
``Http404`` at any point in a view function, Django will catch it and return the
|
||||
standard error page for your application, along with an HTTP error code 404.
|
||||
For convenience, and because it's a good idea to have a consistent 404 error
|
||||
page across your site, Django provides an ``Http404`` exception. If you raise
|
||||
``Http404`` at any point in a view function, Django will catch it and return
|
||||
the standard error page for your application, along with an HTTP error code
|
||||
404.
|
||||
|
||||
Example usage::
|
||||
|
||||
|
||||
@@ -28,9 +28,10 @@ in different ways, depending on the formats for their current locale.
|
||||
Locale aware input in forms
|
||||
===========================
|
||||
|
||||
When formatting is enabled, Django can use localized formats when parsing dates,
|
||||
times and numbers in forms. That means it tries different formats for different
|
||||
locales when guessing the format used by the user when inputting data on forms.
|
||||
When formatting is enabled, Django can use localized formats when parsing
|
||||
dates, times and numbers in forms. That means it tries different formats for
|
||||
different locales when guessing the format used by the user when inputting data
|
||||
on forms.
|
||||
|
||||
.. note::
|
||||
Django uses different formats for displaying data to those it uses for
|
||||
@@ -92,8 +93,8 @@ To activate or deactivate localization for a template block, use:
|
||||
When localization is disabled, the :ref:`localization settings <settings-l10n>`
|
||||
formats are applied.
|
||||
|
||||
See :tfilter:`localize` and :tfilter:`unlocalize` for template filters that will
|
||||
do the same job on a per-variable basis.
|
||||
See :tfilter:`localize` and :tfilter:`unlocalize` for template filters that
|
||||
will do the same job on a per-variable basis.
|
||||
|
||||
Template filters
|
||||
----------------
|
||||
@@ -113,9 +114,9 @@ For example:
|
||||
|
||||
{{ value|localize }}
|
||||
|
||||
To disable localization on a single value, use :tfilter:`unlocalize`. To control
|
||||
localization over a large section of a template, use the :ttag:`localize` template
|
||||
tag.
|
||||
To disable localization on a single value, use :tfilter:`unlocalize`. To
|
||||
control localization over a large section of a template, use the
|
||||
:ttag:`localize` template tag.
|
||||
|
||||
.. templatefilter:: unlocalize
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ Django has full support for :doc:`translation of text
|
||||
|
||||
Essentially, Django does two things:
|
||||
|
||||
* It allows developers and template authors to specify which parts of their apps
|
||||
should be translated or formatted for local languages and cultures.
|
||||
* It allows developers and template authors to specify which parts of their
|
||||
apps should be translated or formatted for local languages and cultures.
|
||||
* It uses these hooks to localize web apps for particular users according to
|
||||
their preferences.
|
||||
|
||||
@@ -46,7 +46,8 @@ here's a simplified definition:
|
||||
localization
|
||||
Writing the translations and local formats. Usually done by translators.
|
||||
|
||||
More details can be found in the `W3C Web Internationalization FAQ`_, the `Wikipedia article`_ or the `GNU gettext documentation`_.
|
||||
More details can be found in the `W3C Web Internationalization FAQ`_, the
|
||||
`Wikipedia article`_ or the `GNU gettext documentation`_.
|
||||
|
||||
.. _W3C Web Internationalization FAQ: https://www.w3.org/International/questions/qa-i18n
|
||||
.. _GNU gettext documentation: https://www.gnu.org/software/gettext/manual/gettext.html#Concepts
|
||||
@@ -87,5 +88,5 @@ Here are some other terms that will help us to handle a common language:
|
||||
A literal that can be translated.
|
||||
|
||||
format file
|
||||
A format file is a Python module that defines the data formats for a given
|
||||
locale.
|
||||
A format file is a Python module that defines the data formats for a
|
||||
given locale.
|
||||
|
||||
@@ -61,9 +61,9 @@ current time, you would write::
|
||||
|
||||
now = datetime.datetime.now()
|
||||
|
||||
When time zone support is enabled (:setting:`USE_TZ=True <USE_TZ>`), Django uses
|
||||
time-zone-aware datetime objects. If your code creates datetime objects, they
|
||||
should be aware too. In this mode, the example above becomes::
|
||||
When time zone support is enabled (:setting:`USE_TZ=True <USE_TZ>`), Django
|
||||
uses time-zone-aware datetime objects. If your code creates datetime objects,
|
||||
they should be aware too. In this mode, the example above becomes::
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
@@ -136,8 +136,9 @@ used.
|
||||
backwards-compatibility with applications that still rely on local time.
|
||||
However, :ref:`as explained above <naive-datetime-objects>`, this isn't
|
||||
entirely reliable, and you should always work with aware datetimes in UTC
|
||||
in your own code. For instance, use :meth:`~datetime.datetime.fromtimestamp`
|
||||
and set the ``tz`` parameter to :obj:`datetime.UTC`.
|
||||
in your own code. For instance, use
|
||||
:meth:`~datetime.datetime.fromtimestamp` and set the ``tz`` parameter to
|
||||
:obj:`datetime.UTC`.
|
||||
|
||||
Selecting the current time zone
|
||||
-------------------------------
|
||||
|
||||
@@ -294,10 +294,10 @@ these words correctly in different contexts, you can use the
|
||||
:func:`django.utils.translation.npgettext` function if the string needs
|
||||
pluralization. Both take a context string as the first variable.
|
||||
|
||||
In the resulting ``.po`` file, the string will then appear as often as there are
|
||||
different contextual markers for the same string (the context will appear on the
|
||||
``msgctxt`` line), allowing the translator to give a different translation for
|
||||
each of them.
|
||||
In the resulting ``.po`` file, the string will then appear as often as there
|
||||
are different contextual markers for the same string (the context will appear
|
||||
on the ``msgctxt`` line), allowing the translator to give a different
|
||||
translation for each of them.
|
||||
|
||||
For example::
|
||||
|
||||
@@ -571,12 +571,12 @@ Similar access to this information is available for template code. See below.
|
||||
Internationalization: in template code
|
||||
======================================
|
||||
|
||||
Translations in :doc:`Django templates </ref/templates/language>` uses two template
|
||||
tags and a slightly different syntax than in Python code. To give your template
|
||||
access to these tags, put ``{% load i18n %}`` toward the top of your template.
|
||||
As with all template tags, this tag needs to be loaded in all templates which
|
||||
use translations, even those templates that extend from other templates which
|
||||
have already loaded the ``i18n`` tag.
|
||||
Translations in :doc:`Django templates </ref/templates/language>` uses two
|
||||
template tags and a slightly different syntax than in Python code. To give your
|
||||
template access to these tags, put ``{% load i18n %}`` toward the top of your
|
||||
template. As with all template tags, this tag needs to be loaded in all
|
||||
templates which use translations, even those templates that extend from other
|
||||
templates which have already loaded the ``i18n`` tag.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -693,8 +693,8 @@ You can use multiple expressions inside a single ``blocktranslate`` tag:
|
||||
.. note:: The previous more verbose format is still supported:
|
||||
``{% blocktranslate with book|title as book_t and author|title as author_t %}``
|
||||
|
||||
Other block tags (for example :ttag:`{% for %}<for>` or :ttag:`{% if %}<if>`) are
|
||||
not allowed inside a ``blocktranslate`` tag.
|
||||
Other block tags (for example :ttag:`{% for %}<for>` or :ttag:`{% if %}<if>`)
|
||||
are not allowed inside a ``blocktranslate`` tag.
|
||||
|
||||
If resolving one of the block arguments fails, ``blocktranslate`` will fall
|
||||
back to the default language by deactivating the currently active language
|
||||
@@ -827,7 +827,8 @@ tag:
|
||||
<p>{% blocktranslate %}A multiline translatable
|
||||
literal.{% endblocktranslate %}</p>
|
||||
|
||||
or with the ``{#`` ... ``#}`` :ref:`one-line comment constructs <template-comments>`:
|
||||
or with the ``{#`` ... ``#}``
|
||||
:ref:`one-line comment constructs <template-comments>`:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
@@ -999,7 +1000,8 @@ There are also some filters available for convenience:
|
||||
* ``{{ LANGUAGE_CODE|language_name }}`` ("German")
|
||||
* ``{{ LANGUAGE_CODE|language_name_local }}`` ("Deutsch")
|
||||
* ``{{ LANGUAGE_CODE|language_bidi }}`` (False)
|
||||
* ``{{ LANGUAGE_CODE|language_name_translated }}`` ("německy", when active language is Czech)
|
||||
* ``{{ LANGUAGE_CODE|language_name_translated }}`` ("německy", when active
|
||||
language is Czech)
|
||||
|
||||
Internationalization: in JavaScript code
|
||||
========================================
|
||||
@@ -1018,8 +1020,8 @@ Django provides an integrated solution for these problems: It passes the
|
||||
translations into JavaScript, so you can call ``gettext``, etc., from within
|
||||
JavaScript.
|
||||
|
||||
The main solution to these problems is the following ``JavaScriptCatalog`` view,
|
||||
which generates a JavaScript code library with functions that mimic the
|
||||
The main solution to these problems is the following ``JavaScriptCatalog``
|
||||
view, which generates a JavaScript code library with functions that mimic the
|
||||
``gettext`` interface, plus an array of translation strings.
|
||||
|
||||
The ``JavaScriptCatalog`` view
|
||||
@@ -1262,8 +1264,8 @@ a word or not:
|
||||
In the simplest case, if no custom pluralization is needed, this returns
|
||||
``false`` for the integer ``1`` and ``true`` for all other numbers.
|
||||
|
||||
However, pluralization is not this simple in all languages. If the language does
|
||||
not support pluralization, an empty value is provided.
|
||||
However, pluralization is not this simple in all languages. If the language
|
||||
does not support pluralization, an empty value is provided.
|
||||
|
||||
Additionally, if there are complex rules around pluralization, the catalog view
|
||||
will render a conditional expression. This will evaluate to either a ``true``
|
||||
@@ -1545,16 +1547,16 @@ Localization: how to create language files
|
||||
==========================================
|
||||
|
||||
Once the string literals of an application have been tagged for later
|
||||
translation, the translation themselves need to be written (or obtained). Here's
|
||||
how that works.
|
||||
translation, the translation themselves need to be written (or obtained).
|
||||
Here's how that works.
|
||||
|
||||
Message files
|
||||
-------------
|
||||
|
||||
The first step is to create a :term:`message file` for a new language. A message
|
||||
file is a plain-text file, representing a single language, that contains all
|
||||
available translation strings and how they should be represented in the given
|
||||
language. Message files have a ``.po`` file extension.
|
||||
The first step is to create a :term:`message file` for a new language. A
|
||||
message file is a plain-text file, representing a single language, that
|
||||
contains all available translation strings and how they should be represented
|
||||
in the given language. Message files have a ``.po`` file extension.
|
||||
|
||||
Django comes with a tool, :djadmin:`django-admin makemessages
|
||||
<makemessages>`, that automates the creation and upkeep of these files.
|
||||
@@ -1591,12 +1593,12 @@ directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the file will be
|
||||
``locale/de/LC_MESSAGES/django.po``.
|
||||
|
||||
When you run ``makemessages`` from the root directory of your project, the
|
||||
extracted strings will be automatically distributed to the proper message files.
|
||||
That is, a string extracted from a file of an app containing a ``locale``
|
||||
directory will go in a message file under that directory. A string extracted
|
||||
from a file of an app without any ``locale`` directory will either go in a
|
||||
message file under the directory listed first in :setting:`LOCALE_PATHS` or
|
||||
will generate an error if :setting:`LOCALE_PATHS` is empty.
|
||||
extracted strings will be automatically distributed to the proper message
|
||||
files. That is, a string extracted from a file of an app containing a
|
||||
``locale`` directory will go in a message file under that directory. A string
|
||||
extracted from a file of an app without any ``locale`` directory will either go
|
||||
in a message file under the directory listed first in :setting:`LOCALE_PATHS`
|
||||
or will generate an error if :setting:`LOCALE_PATHS` is empty.
|
||||
|
||||
By default :djadmin:`django-admin makemessages <makemessages>` examines every
|
||||
file that has the ``.html``, ``.txt`` or ``.py`` file extension. If you want to
|
||||
@@ -1725,13 +1727,13 @@ Compiling message files
|
||||
-----------------------
|
||||
|
||||
After you create your message file -- and each time you make changes to it --
|
||||
you'll need to compile it into a more efficient form, for use by ``gettext``. Do
|
||||
this with the :djadmin:`django-admin compilemessages <compilemessages>`
|
||||
you'll need to compile it into a more efficient form, for use by ``gettext``.
|
||||
Do this with the :djadmin:`django-admin compilemessages <compilemessages>`
|
||||
utility.
|
||||
|
||||
This tool runs over all available ``.po`` files and creates ``.mo`` files, which
|
||||
are binary files optimized for use by ``gettext``. In the same directory from
|
||||
which you ran :djadmin:`django-admin makemessages <makemessages>`, run
|
||||
This tool runs over all available ``.po`` files and creates ``.mo`` files,
|
||||
which are binary files optimized for use by ``gettext``. In the same directory
|
||||
from which you ran :djadmin:`django-admin makemessages <makemessages>`, run
|
||||
:djadmin:`django-admin compilemessages <compilemessages>` like this:
|
||||
|
||||
.. code-block:: shell
|
||||
@@ -1783,11 +1785,11 @@ literals::
|
||||
Creating message files from JavaScript source code
|
||||
--------------------------------------------------
|
||||
|
||||
You create and update the message files the same way as the other Django message
|
||||
files -- with the :djadmin:`django-admin makemessages <makemessages>` tool.
|
||||
The only difference is you need to explicitly specify what in gettext parlance
|
||||
is known as a domain in this case the ``djangojs`` domain, by providing a ``-d
|
||||
djangojs`` parameter, like this:
|
||||
You create and update the message files the same way as the other Django
|
||||
message files -- with the :djadmin:`django-admin makemessages <makemessages>`
|
||||
tool. The only difference is you need to explicitly specify what in gettext
|
||||
parlance is known as a domain in this case the ``djangojs`` domain, by
|
||||
providing a ``-d djangojs`` parameter, like this:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
@@ -1802,11 +1804,12 @@ updating message files, run :djadmin:`django-admin compilemessages
|
||||
``gettext`` on Windows
|
||||
----------------------
|
||||
|
||||
This is only needed for people who either want to extract message IDs or compile
|
||||
message files (``.po``). Translation work itself involves editing existing
|
||||
files of this type, but if you want to create your own message files, or want
|
||||
to test or compile a changed message file, download `a precompiled binary
|
||||
installer <https://mlocati.github.io/articles/gettext-iconv-windows.html>`_.
|
||||
This is only needed for people who either want to extract message IDs or
|
||||
compile message files (``.po``). Translation work itself involves editing
|
||||
existing files of this type, but if you want to create your own message files,
|
||||
or want to test or compile a changed message file, download `a precompiled
|
||||
binary installer
|
||||
<https://mlocati.github.io/articles/gettext-iconv-windows.html>`_.
|
||||
|
||||
You may also use ``gettext`` binaries you have obtained elsewhere, so long as
|
||||
the ``xgettext --version`` command works properly. Do not attempt to use Django
|
||||
@@ -1864,9 +1867,9 @@ The ``set_language`` redirect view
|
||||
|
||||
.. function:: set_language(request)
|
||||
|
||||
As a convenience, Django comes with a view, :func:`django.views.i18n.set_language`,
|
||||
that sets a user's language preference and redirects to a given URL or, by default,
|
||||
back to the previous page.
|
||||
As a convenience, Django comes with a view,
|
||||
:func:`django.views.i18n.set_language`, that sets a user's language preference
|
||||
and redirects to a given URL or, by default, back to the previous page.
|
||||
|
||||
Activate this view by adding the following line to your URLconf::
|
||||
|
||||
@@ -1929,12 +1932,12 @@ redirected in the ``redirect_to`` context variable.
|
||||
Explicitly setting the active language
|
||||
--------------------------------------
|
||||
|
||||
You may want to set the active language for the current session explicitly. Perhaps
|
||||
a user's language preference is retrieved from another system, for example.
|
||||
You've already been introduced to :func:`django.utils.translation.activate`. That
|
||||
applies to the current thread only. To persist the language for the entire
|
||||
session in a cookie, set the :setting:`LANGUAGE_COOKIE_NAME` cookie on the
|
||||
response::
|
||||
You may want to set the active language for the current session explicitly.
|
||||
Perhaps a user's language preference is retrieved from another system, for
|
||||
example. You've already been introduced to
|
||||
:func:`django.utils.translation.activate`. That applies to the current thread
|
||||
only. To persist the language for the entire session in a cookie, set the
|
||||
:setting:`LANGUAGE_COOKIE_NAME` cookie on the response::
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
@@ -2057,9 +2060,9 @@ prefer, then you also need to use the ``LocaleMiddleware``.
|
||||
``LocaleMiddleware`` enables language selection based on data from the request.
|
||||
It customizes content for each user.
|
||||
|
||||
To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
|
||||
to your :setting:`MIDDLEWARE` setting. Because middleware order matters, follow
|
||||
these guidelines:
|
||||
To use ``LocaleMiddleware``, add
|
||||
``'django.middleware.locale.LocaleMiddleware'`` to your :setting:`MIDDLEWARE`
|
||||
setting. Because middleware order matters, follow these guidelines:
|
||||
|
||||
* Make sure it's one of the first middleware installed.
|
||||
* It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
|
||||
@@ -2168,11 +2171,11 @@ in ``request.LANGUAGE_CODE``.
|
||||
How Django discovers translations
|
||||
---------------------------------
|
||||
|
||||
At runtime, Django builds an in-memory unified catalog of literals-translations.
|
||||
To achieve this it looks for translations by following this algorithm regarding
|
||||
the order in which it examines the different file paths to load the compiled
|
||||
:term:`message files <message file>` (``.mo``) and the precedence of multiple
|
||||
translations for the same literal:
|
||||
At runtime, Django builds an in-memory unified catalog of
|
||||
literals-translations. To achieve this it looks for translations by following
|
||||
this algorithm regarding the order in which it examines the different file
|
||||
paths to load the compiled :term:`message files <message file>` (``.mo``) and
|
||||
the precedence of multiple translations for the same literal:
|
||||
|
||||
#. The directories listed in :setting:`LOCALE_PATHS` have the highest
|
||||
precedence, with the ones appearing first having higher precedence than
|
||||
@@ -2180,8 +2183,8 @@ translations for the same literal:
|
||||
#. Then, it looks for and uses if it exists a ``locale`` directory in each
|
||||
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
|
||||
appearing first have higher precedence than the ones appearing later.
|
||||
#. Finally, the Django-provided base translation in :source:`django/conf/locale`
|
||||
is used as a fallback.
|
||||
#. Finally, the Django-provided base translation in
|
||||
:source:`django/conf/locale` is used as a fallback.
|
||||
|
||||
.. seealso::
|
||||
|
||||
@@ -2193,11 +2196,11 @@ translations for the same literal:
|
||||
:setting:`LOCALE_PATHS` directories if you also set
|
||||
:setting:`FORMAT_MODULE_PATH`.
|
||||
|
||||
In all cases the name of the directory containing the translation is expected to
|
||||
be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
|
||||
etc. Untranslated strings for territorial language variants use the translations
|
||||
of the generic language. For example, untranslated ``pt_BR`` strings use ``pt``
|
||||
translations.
|
||||
In all cases the name of the directory containing the translation is expected
|
||||
to be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``,
|
||||
``es_AR``, etc. Untranslated strings for territorial language variants use the
|
||||
translations of the generic language. For example, untranslated ``pt_BR``
|
||||
strings use ``pt`` translations.
|
||||
|
||||
This way, you can write applications that include their own translations, and
|
||||
you can override base translations in your project. Or, you can build a big
|
||||
@@ -2211,9 +2214,10 @@ All message file repositories are structured the same way. They are:
|
||||
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||
|
||||
To create message files, you use the :djadmin:`django-admin makemessages <makemessages>`
|
||||
tool. And you use :djadmin:`django-admin compilemessages <compilemessages>`
|
||||
to produce the binary ``.mo`` files that are used by ``gettext``.
|
||||
To create message files, you use the
|
||||
:djadmin:`django-admin makemessages <makemessages>` tool. And you use
|
||||
:djadmin:`django-admin compilemessages <compilemessages>` to produce the binary
|
||||
``.mo`` files that are used by ``gettext``.
|
||||
|
||||
You can also run :djadmin:`django-admin compilemessages
|
||||
--settings=path.to.settings <compilemessages>` to make the compiler process all
|
||||
@@ -2223,8 +2227,8 @@ Using a non-English base language
|
||||
---------------------------------
|
||||
|
||||
Django makes the general assumption that the original strings in a translatable
|
||||
project are written in English. You can choose another language, but you must be
|
||||
aware of certain limitations:
|
||||
project are written in English. You can choose another language, but you must
|
||||
be aware of certain limitations:
|
||||
|
||||
* ``gettext`` only provides two plural forms for the original messages, so you
|
||||
will also need to provide a translation for the base language to include all
|
||||
|
||||
@@ -47,8 +47,8 @@ for information on how to configure mod_wsgi once you have it
|
||||
installed.
|
||||
|
||||
If you can't use mod_wsgi for some reason, fear not: Django supports many other
|
||||
deployment options. One is :doc:`uWSGI </howto/deployment/wsgi/uwsgi>`; it works
|
||||
very well with `nginx`_. Additionally, Django follows the WSGI spec
|
||||
deployment options. One is :doc:`uWSGI </howto/deployment/wsgi/uwsgi>`; it
|
||||
works very well with `nginx`_. Additionally, Django follows the WSGI spec
|
||||
(:pep:`3333`), which allows it to run on a variety of server platforms.
|
||||
|
||||
.. _Apache: https://httpd.apache.org/
|
||||
@@ -133,8 +133,8 @@ the tables, you can grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and
|
||||
you'll specify the details in your project's settings file, see
|
||||
:setting:`DATABASES` for details.
|
||||
|
||||
If you're using Django's :doc:`testing framework</topics/testing/index>` to test
|
||||
database queries, Django will need permission to create a test database.
|
||||
If you're using Django's :doc:`testing framework</topics/testing/index>` to
|
||||
test database queries, Django will need permission to create a test database.
|
||||
|
||||
.. _PostgreSQL: https://www.postgresql.org/
|
||||
.. _MariaDB: https://mariadb.org/
|
||||
@@ -189,8 +189,8 @@ Installing a distribution-specific package
|
||||
Check the :doc:`distribution specific notes </misc/distributions>` to see if
|
||||
your platform/distribution provides official Django packages/installers.
|
||||
Distribution-provided packages will typically allow for automatic installation
|
||||
of dependencies and supported upgrade paths; however, these packages will rarely
|
||||
contain the latest release of Django.
|
||||
of dependencies and supported upgrade paths; however, these packages will
|
||||
rarely contain the latest release of Django.
|
||||
|
||||
.. _installing-development-version:
|
||||
|
||||
|
||||
@@ -203,11 +203,11 @@ a migration that requires something else to run - for example, you add a
|
||||
migration will contain a dependency on a migration in ``authors``.
|
||||
|
||||
This means that when you run the migrations, the ``authors`` migration runs
|
||||
first and creates the table the ``ForeignKey`` references, and then the migration
|
||||
that makes the ``ForeignKey`` column runs afterward and creates the constraint.
|
||||
If this didn't happen, the migration would try to create the ``ForeignKey``
|
||||
column without the table it's referencing existing and your database would
|
||||
throw an error.
|
||||
first and creates the table the ``ForeignKey`` references, and then the
|
||||
migration that makes the ``ForeignKey`` column runs afterward and creates the
|
||||
constraint. If this didn't happen, the migration would try to create the
|
||||
``ForeignKey`` column without the table it's referencing existing and your
|
||||
database would throw an error.
|
||||
|
||||
This dependency behavior affects most migration operations where you
|
||||
restrict to a single app. Restricting to a single app (either in
|
||||
@@ -485,8 +485,9 @@ that contains a reference to them. On the plus side, methods and managers from
|
||||
these base classes inherit normally, so if you absolutely need access to these
|
||||
you can opt to move them into a superclass.
|
||||
|
||||
To remove old references, you can :ref:`squash migrations <migration-squashing>`
|
||||
or, if there aren't many references, copy them into the migration files.
|
||||
To remove old references, you can :ref:`squash migrations
|
||||
<migration-squashing>` or, if there aren't many references, copy them into the
|
||||
migration files.
|
||||
|
||||
.. _migrations-removing-model-fields:
|
||||
|
||||
@@ -574,8 +575,8 @@ Then, open up the file; it should look something like this::
|
||||
|
||||
Now, all you need to do is create a new function and have
|
||||
:class:`~django.db.migrations.operations.RunPython` use it.
|
||||
:class:`~django.db.migrations.operations.RunPython` expects a callable as its argument
|
||||
which takes two arguments - the first is an :doc:`app registry
|
||||
:class:`~django.db.migrations.operations.RunPython` expects a callable as its
|
||||
argument which takes two arguments - the first is an :doc:`app registry
|
||||
</ref/applications/>` that has the historical versions of all your models
|
||||
loaded into it to match where in your history the migration sits, and the
|
||||
second is a :doc:`SchemaEditor </ref/schema-editor>`, which you can use to
|
||||
@@ -622,8 +623,8 @@ Accessing models from other apps
|
||||
When writing a ``RunPython`` function that uses models from apps other than the
|
||||
one in which the migration is located, the migration's ``dependencies``
|
||||
attribute should include the latest migration of each app that is involved,
|
||||
otherwise you may get an error similar to: ``LookupError: No installed app
|
||||
with label 'myappname'`` when you try to retrieve the model in the ``RunPython``
|
||||
otherwise you may get an error similar to: ``LookupError: No installed app with
|
||||
label 'myappname'`` when you try to retrieve the model in the ``RunPython``
|
||||
function using ``apps.get_model()``.
|
||||
|
||||
In the following example, we have a migration in ``app1`` which needs to use
|
||||
@@ -717,8 +718,9 @@ the name of the squashed migration rather than use an autogenerated one.
|
||||
|
||||
Note that model interdependencies in Django can get very complex, and squashing
|
||||
may result in migrations that do not run; either mis-optimized (in which case
|
||||
you can try again with ``--no-optimize``, though you should also report an issue),
|
||||
or with a ``CircularDependencyError``, in which case you can manually resolve it.
|
||||
you can try again with ``--no-optimize``, though you should also report an
|
||||
issue), or with a ``CircularDependencyError``, in which case you can manually
|
||||
resolve it.
|
||||
|
||||
To manually resolve a ``CircularDependencyError``, break out one of
|
||||
the ForeignKeys in the circular dependency loop into a separate
|
||||
@@ -739,7 +741,8 @@ You can then transition the squashed migration to a normal migration by:
|
||||
- Updating all migrations that depend on the deleted migrations to depend on
|
||||
the squashed migration instead.
|
||||
- Removing the ``replaces`` attribute in the ``Migration`` class of the
|
||||
squashed migration (this is how Django tells that it is a squashed migration).
|
||||
squashed migration (this is how Django tells that it is a squashed
|
||||
migration).
|
||||
|
||||
.. note::
|
||||
You can squash squashed migrations themselves without transitioning to
|
||||
@@ -802,7 +805,8 @@ Django can serialize the following:
|
||||
|
||||
- Unbound methods used from within the class body
|
||||
- Any class reference (must be in module's top-level scope)
|
||||
- Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
|
||||
- Anything with a custom ``deconstruct()`` method
|
||||
(:ref:`see below <custom-deconstruct-method>`)
|
||||
|
||||
.. versionchanged:: 6.0
|
||||
|
||||
@@ -848,9 +852,9 @@ the migration.
|
||||
Adding a ``deconstruct()`` method
|
||||
---------------------------------
|
||||
|
||||
You can let Django serialize your own custom class instances by giving the class
|
||||
a ``deconstruct()`` method. It takes no arguments, and should return a tuple
|
||||
of three things ``(path, args, kwargs)``:
|
||||
You can let Django serialize your own custom class instances by giving the
|
||||
class a ``deconstruct()`` method. It takes no arguments, and should return a
|
||||
tuple of three things ``(path, args, kwargs)``:
|
||||
|
||||
* ``path`` should be the Python path to the class, with the class name included
|
||||
as the last part (for example, ``myapp.custom_things.MyClass``). If your
|
||||
|
||||
@@ -248,7 +248,8 @@ Other database-related tips
|
||||
Enabling :ref:`persistent-database-connections` can speed up connections to the
|
||||
database accounts for a significant part of the request processing time.
|
||||
|
||||
This helps a lot on virtualized hosts with limited network performance, for example.
|
||||
This helps a lot on virtualized hosts with limited network performance, for
|
||||
example.
|
||||
|
||||
HTTP performance
|
||||
================
|
||||
@@ -272,7 +273,8 @@ needed.
|
||||
Compresses responses for all modern browsers, saving bandwidth and transfer
|
||||
time. Note that GZipMiddleware is currently considered a security risk, and is
|
||||
vulnerable to attacks that nullify the protection provided by TLS/SSL. See the
|
||||
warning in :class:`~django.middleware.gzip.GZipMiddleware` for more information.
|
||||
warning in :class:`~django.middleware.gzip.GZipMiddleware` for more
|
||||
information.
|
||||
|
||||
Sessions
|
||||
--------
|
||||
@@ -297,8 +299,8 @@ optimization gains.
|
||||
By taking advantage of web browsers' caching abilities, you can
|
||||
eliminate network hits entirely for a given file after the initial download.
|
||||
|
||||
:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` appends a
|
||||
content-dependent tag to the filenames of :doc:`static files
|
||||
:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` appends
|
||||
a content-dependent tag to the filenames of :doc:`static files
|
||||
</ref/contrib/staticfiles>` to make it safe for browsers to cache them
|
||||
long-term without missing future changes - when a file changes, so will the
|
||||
tag, so browsers will reload the asset automatically.
|
||||
|
||||
@@ -43,9 +43,9 @@ protect the following:
|
||||
|
||||
.. highlighting as html+django fails due to intentionally missing quotes.
|
||||
|
||||
If ``var`` is set to ``'class1 onmouseover=javascript:func()'``, this can result
|
||||
in unauthorized JavaScript execution, depending on how the browser renders
|
||||
imperfect HTML. (Quoting the attribute value would fix this case.)
|
||||
If ``var`` is set to ``'class1 onmouseover=javascript:func()'``, this can
|
||||
result in unauthorized JavaScript execution, depending on how the browser
|
||||
renders imperfect HTML. (Quoting the attribute value would fix this case.)
|
||||
|
||||
It is also important to be particularly careful when using ``is_safe`` with
|
||||
custom template tags, the :tfilter:`safe` template tag, :mod:`mark_safe
|
||||
@@ -65,13 +65,13 @@ Cross site request forgery (CSRF) protection
|
||||
CSRF attacks allow a malicious user to execute actions using the credentials
|
||||
of another user without that user's knowledge or consent.
|
||||
|
||||
Django has built-in protection against most types of CSRF attacks, providing you
|
||||
have :ref:`enabled and used it <using-csrf>` where appropriate. However, as with
|
||||
any mitigation technique, there are limitations. For example, it is possible to
|
||||
disable the CSRF module globally or for particular views. You should only do
|
||||
this if you know what you are doing. There are other :ref:`limitations
|
||||
<csrf-limitations>` if your site has subdomains that are outside of your
|
||||
control.
|
||||
Django has built-in protection against most types of CSRF attacks, providing
|
||||
you have :ref:`enabled and used it <using-csrf>` where appropriate. However, as
|
||||
with any mitigation technique, there are limitations. For example, it is
|
||||
possible to disable the CSRF module globally or for particular views. You
|
||||
should only do this if you know what you are doing. There are other
|
||||
:ref:`limitations <csrf-limitations>` if your site has subdomains that are
|
||||
outside of your control.
|
||||
|
||||
:ref:`CSRF protection works <how-csrf-works>` by checking for a secret in each
|
||||
POST request. This ensures that a malicious user cannot "replay" a form POST to
|
||||
@@ -107,8 +107,9 @@ Django also gives developers power to write :ref:`raw queries
|
||||
<executing-raw-queries>` or execute :ref:`custom sql <executing-custom-sql>`.
|
||||
These capabilities should be used sparingly and you should always be careful to
|
||||
properly escape any parameters that the user can control. In addition, you
|
||||
should exercise caution when using :meth:`~django.db.models.query.QuerySet.extra`
|
||||
and :class:`~django.db.models.expressions.RawSQL`.
|
||||
should exercise caution when using
|
||||
:meth:`~django.db.models.query.QuerySet.extra` and
|
||||
:class:`~django.db.models.expressions.RawSQL`.
|
||||
|
||||
Clickjacking protection
|
||||
=======================
|
||||
@@ -117,12 +118,12 @@ Clickjacking is a type of attack where a malicious site wraps another site
|
||||
in a frame. This attack can result in an unsuspecting user being tricked
|
||||
into performing unintended actions on the target site.
|
||||
|
||||
Django contains :ref:`clickjacking protection <clickjacking-prevention>` in
|
||||
the form of the
|
||||
:mod:`X-Frame-Options middleware <django.middleware.clickjacking.XFrameOptionsMiddleware>`
|
||||
which in a supporting browser can prevent a site from being rendered inside
|
||||
a frame. It is possible to disable the protection on a per view basis
|
||||
or to configure the exact header value sent.
|
||||
Django contains :ref:`clickjacking protection <clickjacking-prevention>` in the
|
||||
form of the :mod:`X-Frame-Options middleware
|
||||
<django.middleware.clickjacking.XFrameOptionsMiddleware>` which in a supporting
|
||||
browser can prevent a site from being rendered inside a frame. It is possible
|
||||
to disable the protection on a per view basis or to configure the exact header
|
||||
value sent.
|
||||
|
||||
The middleware is strongly recommended for any site that does not need to have
|
||||
its pages wrapped in a frame by third party sites, or only needs to allow that
|
||||
@@ -159,21 +160,21 @@ server, there are some additional steps you may need:
|
||||
If a browser connects initially via HTTP, which is the default for most
|
||||
browsers, it is possible for existing cookies to be leaked. For this reason,
|
||||
you should set your :setting:`SESSION_COOKIE_SECURE` and
|
||||
:setting:`CSRF_COOKIE_SECURE` settings to ``True``. This instructs the browser
|
||||
to only send these cookies over HTTPS connections. Note that this will mean
|
||||
that sessions will not work over HTTP, and the CSRF protection will prevent
|
||||
any POST data being accepted over HTTP (which will be fine if you are
|
||||
:setting:`CSRF_COOKIE_SECURE` settings to ``True``. This instructs the
|
||||
browser to only send these cookies over HTTPS connections. Note that this
|
||||
will mean that sessions will not work over HTTP, and the CSRF protection will
|
||||
prevent any POST data being accepted over HTTP (which will be fine if you are
|
||||
redirecting all HTTP traffic to HTTPS).
|
||||
|
||||
* Use :ref:`http-strict-transport-security` (HSTS)
|
||||
|
||||
HSTS is an HTTP header that informs a browser that all future connections
|
||||
to a particular site should always use HTTPS. Combined with redirecting
|
||||
requests over HTTP to HTTPS, this will ensure that connections always enjoy
|
||||
the added security of SSL provided one successful connection has occurred.
|
||||
HSTS may either be configured with :setting:`SECURE_HSTS_SECONDS`,
|
||||
:setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`, and :setting:`SECURE_HSTS_PRELOAD`,
|
||||
or on the web server.
|
||||
HSTS is an HTTP header that informs a browser that all future connections to
|
||||
a particular site should always use HTTPS. Combined with redirecting requests
|
||||
over HTTP to HTTPS, this will ensure that connections always enjoy the added
|
||||
security of SSL provided one successful connection has occurred. HSTS may
|
||||
either be configured with :setting:`SECURE_HSTS_SECONDS`,
|
||||
:setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`, and
|
||||
:setting:`SECURE_HSTS_PRELOAD`, or on the web server.
|
||||
|
||||
.. _host-headers-virtual-hosting:
|
||||
|
||||
@@ -198,8 +199,8 @@ For more details see the full :setting:`ALLOWED_HOSTS` documentation.
|
||||
|
||||
.. warning::
|
||||
|
||||
Previous versions of this document recommended configuring your web server to
|
||||
ensure it validates incoming HTTP ``Host`` headers. While this is still
|
||||
Previous versions of this document recommended configuring your web server
|
||||
to ensure it validates incoming HTTP ``Host`` headers. While this is still
|
||||
recommended, in many common web servers a configuration that seems to
|
||||
validate the ``Host`` header may not in fact do so. For instance, even if
|
||||
Apache is configured such that your Django site is served from a non-default
|
||||
@@ -255,9 +256,9 @@ User-uploaded content
|
||||
can be easily set using the LimitRequestBody_ directive.
|
||||
|
||||
* If you are serving your own static files, be sure that handlers like Apache's
|
||||
``mod_php``, which would execute static files as code, are disabled. You don't
|
||||
want users to be able to execute arbitrary code by uploading and requesting a
|
||||
specially crafted file.
|
||||
``mod_php``, which would execute static files as code, are disabled. You
|
||||
don't want users to be able to execute arbitrary code by uploading and
|
||||
requesting a specially crafted file.
|
||||
|
||||
* Django's media upload handling poses some vulnerabilities when that media is
|
||||
served in ways that do not follow security best practices. Specifically, an
|
||||
@@ -362,8 +363,8 @@ security protection of the web server, operating system and other components.
|
||||
* It is a good idea to limit the accessibility of your caching system and
|
||||
database using a firewall.
|
||||
* Take a look at the Open Web Application Security Project (OWASP) `Top 10
|
||||
list`_ which identifies some common vulnerabilities in web applications. While
|
||||
Django has tools to address some of the issues, other issues must be
|
||||
list`_ which identifies some common vulnerabilities in web applications.
|
||||
While Django has tools to address some of the issues, other issues must be
|
||||
accounted for in the design of your project.
|
||||
* Mozilla discusses various topics regarding `web security`_. Their
|
||||
pages also include security principles that apply to any system.
|
||||
|
||||
@@ -21,8 +21,8 @@ At the highest level, you can serialize data like this::
|
||||
|
||||
data = serializers.serialize("xml", SomeModel.objects.all())
|
||||
|
||||
The arguments to the ``serialize`` function are the format to serialize the data
|
||||
to (see `Serialization formats`_) and a
|
||||
The arguments to the ``serialize`` function are the format to serialize the
|
||||
data to (see `Serialization formats`_) and a
|
||||
:class:`~django.db.models.query.QuerySet` to serialize. (Actually, the second
|
||||
argument can be any iterator that yields Django model instances, but it'll
|
||||
almost always be a QuerySet).
|
||||
@@ -61,8 +61,8 @@ specify a ``fields`` argument to the serializer::
|
||||
data = serializers.serialize("xml", SomeModel.objects.all(), fields=["name", "size"])
|
||||
|
||||
In this example, only the ``name`` and ``size`` attributes of each model will
|
||||
be serialized. The primary key is always serialized as the ``pk`` element in the
|
||||
resulting output; it never appears in the ``fields`` part.
|
||||
be serialized. The primary key is always serialized as the ``pk`` element in
|
||||
the resulting output; it never appears in the ``fields`` part.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -224,7 +224,8 @@ the ``auth.User`` model has such a relation to the ``auth.Permission`` model:
|
||||
</field>
|
||||
</object>
|
||||
|
||||
This example links the given user with the permission models with PKs 46 and 47.
|
||||
This example links the given user with the permission models with PKs 46 and
|
||||
47.
|
||||
|
||||
.. admonition:: Control characters
|
||||
|
||||
@@ -604,9 +605,9 @@ When ``use_natural_foreign_keys=True`` is specified, Django will use the
|
||||
``natural_key()`` method to serialize any foreign key reference to objects
|
||||
of the type that defines the method.
|
||||
|
||||
When ``use_natural_primary_keys=True`` is specified, Django will not provide the
|
||||
primary key in the serialized data of this object since it can be calculated
|
||||
during deserialization::
|
||||
When ``use_natural_primary_keys=True`` is specified, Django will not provide
|
||||
the primary key in the serialized data of this object since it can be
|
||||
calculated during deserialization::
|
||||
|
||||
...
|
||||
{
|
||||
|
||||
@@ -160,7 +160,8 @@ read it. This is especially important in a shared-hosting environment.
|
||||
Available settings
|
||||
==================
|
||||
|
||||
For a full list of available settings, see the :doc:`settings reference </ref/settings>`.
|
||||
For a full list of available settings, see the
|
||||
:doc:`settings reference </ref/settings>`.
|
||||
|
||||
Creating your own settings
|
||||
==========================
|
||||
|
||||
@@ -83,7 +83,8 @@ function or method::
|
||||
print("Request finished!")
|
||||
|
||||
Notice that the function takes a ``sender`` argument, along with wildcard
|
||||
keyword arguments (``**kwargs``); all signal handlers must take these arguments.
|
||||
keyword arguments (``**kwargs``); all signal handlers must take these
|
||||
arguments.
|
||||
|
||||
We'll look at senders :ref:`a bit later <connecting-to-specific-signals>`, but
|
||||
right now look at the ``**kwargs`` argument. All signals send keyword
|
||||
@@ -181,9 +182,9 @@ Connecting to signals sent by specific senders
|
||||
|
||||
Some signals get sent many times, but you'll only be interested in receiving a
|
||||
certain subset of those signals. For example, consider the
|
||||
:data:`django.db.models.signals.pre_save` signal sent before a model gets saved.
|
||||
Most of the time, you don't need to know when *any* model gets saved -- just
|
||||
when one *specific* model is saved.
|
||||
:data:`django.db.models.signals.pre_save` signal sent before a model gets
|
||||
saved. Most of the time, you don't need to know when *any* model gets saved --
|
||||
just when one *specific* model is saved.
|
||||
|
||||
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
|
||||
@@ -201,9 +202,9 @@ signals sent by some model::
|
||||
The ``my_handler`` function will only be called when an instance of ``MyModel``
|
||||
is saved.
|
||||
|
||||
Different signals use different objects as their senders; you'll need to consult
|
||||
the :doc:`built-in signal documentation </ref/signals>` for details of each
|
||||
particular signal.
|
||||
Different signals use different objects as their senders; you'll need to
|
||||
consult the :doc:`built-in signal documentation </ref/signals>` for details of
|
||||
each particular signal.
|
||||
|
||||
.. _preventing-duplicate-signals:
|
||||
|
||||
@@ -298,7 +299,8 @@ be notified of a signal in the face of an error.
|
||||
|
||||
``send_robust()`` catches all errors derived from Python's ``Exception`` class,
|
||||
and ensures all receivers are notified of the signal. If an error occurs, the
|
||||
error instance is returned in the tuple pair for the receiver that raised the error.
|
||||
error instance is returned in the tuple pair for the receiver that raised the
|
||||
error.
|
||||
|
||||
The tracebacks are present on the ``__traceback__`` attribute of the errors
|
||||
returned when calling ``send_robust()``.
|
||||
|
||||
@@ -381,9 +381,10 @@ must provide a ``render()`` method with the following signature:
|
||||
If ``context`` is provided, it must be a :class:`dict`. If it isn't
|
||||
provided, the engine will render the template with an empty context.
|
||||
|
||||
If ``request`` is provided, it must be an :class:`~django.http.HttpRequest`.
|
||||
Then the engine must make it, as well as the CSRF token, available in the
|
||||
template. How this is achieved is up to each backend.
|
||||
If ``request`` is provided, it must be an
|
||||
:class:`~django.http.HttpRequest`. Then the engine must make it, as well as
|
||||
the CSRF token, available in the template. How this is achieved is up to
|
||||
each backend.
|
||||
|
||||
Here's an example of the search algorithm. For this example the
|
||||
:setting:`TEMPLATES` setting is::
|
||||
@@ -411,8 +412,8 @@ will look for, in order:
|
||||
* ``/home/html/default/story_detail.html`` (``'django'`` engine)
|
||||
* ``/home/html/jinja2/story_detail.html`` (``'jinja2'`` engine)
|
||||
|
||||
If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``,
|
||||
here's what Django will look for:
|
||||
If you call ``select_template(['story_253_detail.html',
|
||||
'story_detail.html'])``, here's what Django will look for:
|
||||
|
||||
* ``/home/html/example.com/story_253_detail.html`` (``'django'`` engine)
|
||||
* ``/home/html/default/story_253_detail.html`` (``'django'`` engine)
|
||||
@@ -634,12 +635,12 @@ adds defaults that differ from Jinja2's for a few options:
|
||||
|
||||
.. admonition:: Using context processors with Jinja2 templates is discouraged.
|
||||
|
||||
Context processors are useful with Django templates because Django templates
|
||||
don't support calling functions with arguments. Since Jinja2 doesn't have
|
||||
that limitation, it's recommended to put the function that you would use as a
|
||||
context processor in the global variables available to the template using
|
||||
``jinja2.Environment`` as described below. You can then call that function in
|
||||
the template:
|
||||
Context processors are useful with Django templates because Django
|
||||
templates don't support calling functions with arguments. Since Jinja2
|
||||
doesn't have that limitation, it's recommended to put the function that you
|
||||
would use as a context processor in the global variables available to the
|
||||
template using ``jinja2.Environment`` as described below. You can then call
|
||||
that function in the template:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
@@ -655,8 +656,8 @@ adds defaults that differ from Jinja2's for a few options:
|
||||
* Needing the result in every template.
|
||||
* Using the result multiple times in each template.
|
||||
|
||||
Unless all of these conditions are met, passing a function to the template is
|
||||
more in line with the design of Jinja2.
|
||||
Unless all of these conditions are met, passing a function to the template
|
||||
is more in line with the design of Jinja2.
|
||||
|
||||
The default configuration is purposefully kept to a minimum. If a template is
|
||||
rendered with a request (e.g. when using :py:func:`~django.shortcuts.render`),
|
||||
|
||||
@@ -11,8 +11,8 @@ Writing and running tests
|
||||
reference </topics/testing/tools>`, and the :doc:`advanced testing topics
|
||||
</topics/testing/advanced>`.
|
||||
|
||||
This document is split into two primary sections. First, we explain how to write
|
||||
tests with Django. Then, we explain how to run them.
|
||||
This document is split into two primary sections. First, we explain how to
|
||||
write tests with Django. Then, we explain how to run them.
|
||||
|
||||
Writing tests
|
||||
=============
|
||||
@@ -187,12 +187,12 @@ test database is created by the user specified by :setting:`USER`, so you'll
|
||||
need to make sure that the given user account has sufficient privileges to
|
||||
create a new database on the system.
|
||||
|
||||
For fine-grained control over the character encoding of your test
|
||||
database, use the :setting:`CHARSET <TEST_CHARSET>` TEST option. If you're using
|
||||
MySQL, you can also use the :setting:`COLLATION <TEST_COLLATION>` option to
|
||||
control the particular collation used by the test database. See the
|
||||
:doc:`settings documentation </ref/settings>` for details of these
|
||||
and other advanced settings.
|
||||
For fine-grained control over the character encoding of your test database, use
|
||||
the :setting:`CHARSET <TEST_CHARSET>` TEST option. If you're using MySQL, you
|
||||
can also use the :setting:`COLLATION <TEST_COLLATION>` option to control the
|
||||
particular collation used by the test database. See the :doc:`settings
|
||||
documentation </ref/settings>` for details of these and other advanced
|
||||
settings.
|
||||
|
||||
If using an SQLite in-memory database with SQLite, `shared cache
|
||||
<https://www.sqlite.org/sharedcache.html>`_ is enabled, so you can write tests
|
||||
@@ -212,7 +212,8 @@ with ability to share the database between threads.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The :ref:`advanced multi-db testing topics <topics-testing-advanced-multidb>`.
|
||||
The :ref:`advanced multi-db testing topics
|
||||
<topics-testing-advanced-multidb>`.
|
||||
|
||||
.. _order-of-tests:
|
||||
|
||||
|
||||
@@ -301,12 +301,12 @@ Use the ``django.test.Client`` class to make requests.
|
||||
... c.post("/customers/wishes/", {"name": "fred", "attachment": fp})
|
||||
...
|
||||
|
||||
You may also provide any file-like object (e.g., :class:`~io.StringIO` or
|
||||
:class:`~io.BytesIO`) as a file handle. If you're uploading to an
|
||||
You may also provide any file-like object (e.g., :class:`~io.StringIO`
|
||||
or :class:`~io.BytesIO`) as a file handle. If you're uploading to an
|
||||
:class:`~django.db.models.ImageField`, the object needs a ``name``
|
||||
attribute that passes the
|
||||
:data:`~django.core.validators.validate_image_file_extension` validator.
|
||||
For example:
|
||||
:data:`~django.core.validators.validate_image_file_extension`
|
||||
validator. For example:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
@@ -341,8 +341,8 @@ Use the ``django.test.Client`` class to make requests.
|
||||
... "/login/", {"name": "fred", "passwd": "secret"}, query_params={"visitor": "true"}
|
||||
... )
|
||||
|
||||
... the view handling this request could interrogate request.POST
|
||||
to retrieve the username and password, and could interrogate request.GET
|
||||
... the view handling this request could interrogate request.POST to
|
||||
retrieve the username and password, and could interrogate request.GET
|
||||
to determine if the user was a visitor.
|
||||
|
||||
If you set ``follow`` to ``True`` the client will follow any redirects
|
||||
@@ -417,10 +417,10 @@ Use the ``django.test.Client`` class to make requests.
|
||||
|
||||
*Asynchronous version*: ``alogin()``
|
||||
|
||||
If your site uses Django's :doc:`authentication system</topics/auth/index>`
|
||||
and you deal with logging in users, you can use the test client's
|
||||
``login()`` method to simulate the effect of a user logging into the
|
||||
site.
|
||||
If your site uses Django's
|
||||
:doc:`authentication system</topics/auth/index>` and you deal with
|
||||
logging in users, you can use the test client's ``login()`` method to
|
||||
simulate the effect of a user logging into the site.
|
||||
|
||||
After you call this method, the test client will have all the cookies
|
||||
and session data required to pass any login-based tests that may form
|
||||
@@ -493,9 +493,10 @@ Use the ``django.test.Client`` class to make requests.
|
||||
|
||||
*Asynchronous version*: ``alogout()``
|
||||
|
||||
If your site uses Django's :doc:`authentication system</topics/auth/index>`,
|
||||
the ``logout()`` method can be used to simulate the effect of a user
|
||||
logging out of your site.
|
||||
If your site uses Django's
|
||||
:doc:`authentication system</topics/auth/index>`, the ``logout()``
|
||||
method can be used to simulate the effect of a user logging out of your
|
||||
site.
|
||||
|
||||
After you call this method, the test client will have all the cookies
|
||||
and session data cleared to defaults. Subsequent requests will appear
|
||||
@@ -525,11 +526,12 @@ Specifically, a ``Response`` object has the following attributes:
|
||||
|
||||
.. attribute:: context
|
||||
|
||||
The template ``Context`` instance that was used to render the template that
|
||||
produced the response content.
|
||||
The template ``Context`` instance that was used to render the template
|
||||
that produced the response content.
|
||||
|
||||
If the rendered page used multiple templates, then ``context`` will be a
|
||||
list of ``Context`` objects, in the order in which they were rendered.
|
||||
If the rendered page used multiple templates, then ``context`` will be
|
||||
a list of ``Context`` objects, in the order in which they were
|
||||
rendered.
|
||||
|
||||
Regardless of the number of templates used during rendering, you can
|
||||
retrieve context values using the ``[]`` operator. For example, the
|
||||
@@ -646,9 +648,9 @@ The only exceptions that are not visible to the test client are
|
||||
exceptions internally and converts them into the appropriate HTTP response
|
||||
codes. In these cases, you can check ``response.status_code`` in your test.
|
||||
|
||||
If ``Client.raise_request_exception`` is ``False``, the test client will return a
|
||||
500 response as would be returned to a browser. The response has the attribute
|
||||
:attr:`~Response.exc_info` to provide information about the unhandled
|
||||
If ``Client.raise_request_exception`` is ``False``, the test client will return
|
||||
a 500 response as would be returned to a browser. The response has the
|
||||
attribute :attr:`~Response.exc_info` to provide information about the unhandled
|
||||
exception.
|
||||
|
||||
Persistent state
|
||||
@@ -772,7 +774,8 @@ Provided test case classes
|
||||
==========================
|
||||
|
||||
Normal Python unit test classes extend a base class of
|
||||
:class:`unittest.TestCase`. Django provides a few extensions of this base class:
|
||||
:class:`unittest.TestCase`. Django provides a few extensions of this base
|
||||
class:
|
||||
|
||||
.. _testcase_hierarchy_diagram:
|
||||
|
||||
@@ -811,12 +814,13 @@ A subclass of :class:`unittest.TestCase` that adds this functionality:
|
||||
* Verifying that two :meth:`URLs <SimpleTestCase.assertURLEqual>` are equal.
|
||||
* Verifying an HTTP :meth:`redirect <SimpleTestCase.assertRedirects>` is
|
||||
performed by the app.
|
||||
* Robustly testing two :meth:`HTML fragments <SimpleTestCase.assertHTMLEqual>`
|
||||
for equality/inequality or :meth:`containment <SimpleTestCase.assertInHTML>`.
|
||||
* Robustly testing two :meth:`HTML fragments
|
||||
<SimpleTestCase.assertHTMLEqual>` for equality/inequality or
|
||||
:meth:`containment <SimpleTestCase.assertInHTML>`.
|
||||
* Robustly testing two :meth:`XML fragments <SimpleTestCase.assertXMLEqual>`
|
||||
for equality/inequality.
|
||||
* Robustly testing two :meth:`JSON fragments <SimpleTestCase.assertJSONEqual>`
|
||||
for equality.
|
||||
* Robustly testing two :meth:`JSON fragments
|
||||
<SimpleTestCase.assertJSONEqual>` for equality.
|
||||
|
||||
* The ability to run tests with :ref:`modified settings <overriding-settings>`.
|
||||
* Using the :attr:`~SimpleTestCase.client` :class:`~django.test.Client`.
|
||||
@@ -901,9 +905,9 @@ to test the effects of commit and rollback:
|
||||
.. warning::
|
||||
|
||||
``TestCase`` running on a database that does not support rollback (e.g. MySQL
|
||||
with the MyISAM storage engine), and all instances of ``TransactionTestCase``,
|
||||
will roll back at the end of the test by deleting all data from the test
|
||||
database.
|
||||
with the MyISAM storage engine), and all instances of
|
||||
``TransactionTestCase``, will roll back at the end of the test by deleting
|
||||
all data from the test database.
|
||||
|
||||
Apps :ref:`will not see their data reloaded <test-case-serialized-rollback>`;
|
||||
if you need this functionality (for example, third-party apps should enable
|
||||
@@ -1105,9 +1109,9 @@ out the `full reference`_ for more details.
|
||||
lambda driver: driver.find_element(By.TAG_NAME, "body")
|
||||
)
|
||||
|
||||
The tricky thing here is that there's really no such thing as a "page load,"
|
||||
especially in modern web apps that generate HTML dynamically after the
|
||||
server generates the initial document. So, checking for the presence of
|
||||
The tricky thing here is that there's really no such thing as a "page
|
||||
load," especially in modern web apps that generate HTML dynamically after
|
||||
the server generates the initial document. So, checking for the presence of
|
||||
``<body>`` in the response might not necessarily be appropriate for all use
|
||||
cases. Please refer to the `Selenium FAQ`_ and `Selenium documentation`_
|
||||
for more information.
|
||||
@@ -1335,9 +1339,9 @@ Overriding settings
|
||||
|
||||
.. warning::
|
||||
|
||||
Use the functions below to temporarily alter the value of settings in tests.
|
||||
Don't manipulate ``django.conf.settings`` directly as Django won't restore
|
||||
the original values after such manipulations.
|
||||
Use the functions below to temporarily alter the value of settings in
|
||||
tests. Don't manipulate ``django.conf.settings`` directly as Django won't
|
||||
restore the original values after such manipulations.
|
||||
|
||||
.. method:: SimpleTestCase.settings()
|
||||
|
||||
@@ -1595,8 +1599,8 @@ For more detail on email services during tests, see `Email services`_ below.
|
||||
Assertions
|
||||
----------
|
||||
|
||||
As Python's normal :class:`unittest.TestCase` class implements assertion methods
|
||||
such as :meth:`~unittest.TestCase.assertTrue` and
|
||||
As Python's normal :class:`unittest.TestCase` class implements assertion
|
||||
methods such as :meth:`~unittest.TestCase.assertTrue` and
|
||||
:meth:`~unittest.TestCase.assertEqual`, Django's custom :class:`TestCase` class
|
||||
provides a number of custom assertion methods that are useful for testing web
|
||||
applications:
|
||||
@@ -1641,7 +1645,8 @@ your test suite.
|
||||
error messages.
|
||||
:param field_args: the args passed to instantiate the field.
|
||||
:param field_kwargs: the kwargs passed to instantiate the field.
|
||||
:param empty_value: the expected clean output for inputs in ``empty_values``.
|
||||
:param empty_value: the expected clean output for inputs in
|
||||
``empty_values``.
|
||||
|
||||
For example, the following code tests that an ``EmailField`` accepts
|
||||
``a@a.com`` as a valid email address, but rejects ``aaa`` with a reasonable
|
||||
@@ -1660,8 +1665,8 @@ your test suite.
|
||||
validated (``assertFormError()`` will automatically call ``full_clean()``
|
||||
on the form).
|
||||
|
||||
``field`` is the name of the field on the form to check. To check the form's
|
||||
:meth:`non-field errors <django.forms.Form.non_field_errors>`, use
|
||||
``field`` is the name of the field on the form to check. To check the
|
||||
form's :meth:`non-field errors <django.forms.Form.non_field_errors>`, use
|
||||
``field=None``.
|
||||
|
||||
``errors`` is a list of all the error strings that the field is expected to
|
||||
@@ -1763,8 +1768,8 @@ your test suite.
|
||||
particularly useful if ``expected_url`` isn't part of your Django app.
|
||||
|
||||
Scheme is handled correctly when making comparisons between two URLs. If
|
||||
there isn't any scheme specified in the location where we are redirected to,
|
||||
the original request's scheme is used. If present, the scheme in
|
||||
there isn't any scheme specified in the location where we are redirected
|
||||
to, the original request's scheme is used. If present, the scheme in
|
||||
``expected_url`` is the one used to make the comparisons to.
|
||||
|
||||
.. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)
|
||||
@@ -1841,8 +1846,8 @@ your test suite.
|
||||
Asserts that the HTML fragment ``needle`` is contained in the ``haystack``
|
||||
once.
|
||||
|
||||
If the ``count`` integer argument is specified, then additionally the number
|
||||
of ``needle`` occurrences will be strictly verified.
|
||||
If the ``count`` integer argument is specified, then additionally the
|
||||
number of ``needle`` occurrences will be strictly verified.
|
||||
|
||||
Whitespace in most cases is ignored, and attribute ordering is not
|
||||
significant. See :meth:`~SimpleTestCase.assertHTMLEqual` for more details.
|
||||
@@ -1865,8 +1870,8 @@ your test suite.
|
||||
|
||||
.. method:: SimpleTestCase.assertJSONNotEqual(raw, expected_data, msg=None)
|
||||
|
||||
Asserts that the JSON fragments ``raw`` and ``expected_data`` are *not* equal.
|
||||
See :meth:`~SimpleTestCase.assertJSONEqual` for further details.
|
||||
Asserts that the JSON fragments ``raw`` and ``expected_data`` are *not*
|
||||
equal. See :meth:`~SimpleTestCase.assertJSONEqual` for further details.
|
||||
|
||||
Output in case of error can be customized with the ``msg`` argument.
|
||||
|
||||
@@ -1880,10 +1885,10 @@ your test suite.
|
||||
|
||||
By default, the comparison is also ordering dependent. If ``qs`` doesn't
|
||||
provide an implicit ordering, you can set the ``ordered`` parameter to
|
||||
``False``, which turns the comparison into a ``collections.Counter`` comparison.
|
||||
If the order is undefined (if the given ``qs`` isn't ordered and the
|
||||
comparison is against more than one ordered value), a ``ValueError`` is
|
||||
raised.
|
||||
``False``, which turns the comparison into a ``collections.Counter``
|
||||
comparison. If the order is undefined (if the given ``qs`` isn't ordered
|
||||
and the comparison is against more than one ordered value), a
|
||||
``ValueError`` is raised.
|
||||
|
||||
Output in case of error can be customized with the ``msg`` argument.
|
||||
|
||||
@@ -2018,9 +2023,9 @@ creates.
|
||||
.. warning::
|
||||
|
||||
If you are using test decorators, they must be async-compatible to ensure
|
||||
they work correctly. Django's built-in decorators will behave correctly, but
|
||||
third-party ones may appear to not execute (they will "wrap" the wrong part
|
||||
of the execution flow and not your test).
|
||||
they work correctly. Django's built-in decorators will behave correctly,
|
||||
but third-party ones may appear to not execute (they will "wrap" the wrong
|
||||
part of the execution flow and not your test).
|
||||
|
||||
If you need to use these decorators, then you should decorate your test
|
||||
methods with :func:`~asgiref.sync.async_to_sync` *inside* of them instead::
|
||||
|
||||
Reference in New Issue
Block a user