Refs #14645 -- Documented bug with exclude() and multi-value relations

This commit is contained in:
David Seddon 2015-01-12 16:11:11 +00:00 committed by Tim Graham
parent d94449f37a
commit 6770b7ecd2
1 changed files with 29 additions and 10 deletions

View File

@ -546,8 +546,7 @@ find entries linked to tags called *"music"* and *"bands"* or we might want an
entry that contains a tag with a name of *"music"* and a status of *"public"*. entry that contains a tag with a name of *"music"* and a status of *"public"*.
To handle both of these situations, Django has a consistent way of processing To handle both of these situations, Django has a consistent way of processing
:meth:`~django.db.models.query.QuerySet.filter` and :meth:`~django.db.models.query.QuerySet.filter` calls. Everything inside a
:meth:`~django.db.models.query.QuerySet.exclude` calls. Everything inside a
single :meth:`~django.db.models.query.QuerySet.filter` call is applied single :meth:`~django.db.models.query.QuerySet.filter` call is applied
simultaneously to filter out items matching all those requirements. Successive simultaneously to filter out items matching all those requirements. Successive
:meth:`~django.db.models.query.QuerySet.filter` calls further restrict the set :meth:`~django.db.models.query.QuerySet.filter` calls further restrict the set
@ -581,14 +580,34 @@ that were published in 2008. The entries selected by the second filter may or
may not be the same as the entries in the first filter. We are filtering the may not be the same as the entries in the first filter. We are filtering the
``Blog`` items with each filter statement, not the ``Entry`` items. ``Blog`` items with each filter statement, not the ``Entry`` items.
All of this behavior also applies to .. note::
:meth:`~django.db.models.query.QuerySet.exclude`: all the conditions in a
single :meth:`~django.db.models.query.QuerySet.exclude` statement apply to a The behavior of :meth:`~django.db.models.query.QuerySet.filter` for queries
single instance (if those conditions are talking about the same multi-valued that span multi-value relationships, as described above, is not implemented
relation). Conditions in subsequent equivalently for :meth:`~django.db.models.query.QuerySet.exclude`. Instead,
:meth:`~django.db.models.query.QuerySet.filter` or the conditions in a single :meth:`~django.db.models.query.QuerySet.exclude`
:meth:`~django.db.models.query.QuerySet.exclude` calls that refer to the same call will not necessarily refer to the same item.
relation may end up filtering on different linked objects.
For example, the following query would exclude blogs that contain *both*
entries with *"Lennon"* in the headline *and* entries published in 2008::
Blog.objects.exclude(
entry__headline__contains='Lennon',
entry__pub_date__year=2008,
)
However, unlike the behavior when using
:meth:`~django.db.models.query.QuerySet.filter`, this will not limit blogs
based on entries that satisfying both conditions. In order to do that, i.e.
to select all blogs that do not contain entries published with *"Lennon"*
that were published in 2008, you need to make two queries::
Blog.objects.exclude(
entry=Entry.objects.filter(
headline__contains='Lennon',
pub_date__year=2008,
),
)
.. _using-f-expressions-in-filters: .. _using-f-expressions-in-filters: