diff options
| author | David Seddon <david@seddonym.me> | 2015-01-12 16:11:11 +0000 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-03-20 17:52:05 -0400 |
| commit | b46643a47e82fb56d589b9584877f823dabc3fdf (patch) | |
| tree | ce682cff64cacf090cf016e439ab1986959cf037 | |
| parent | 5cad259c12bed21ad80b68be1ec15ec3c48b6a3e (diff) | |
[1.7.x] Refs #14645 -- Documented bug with exclude() and multi-value relations
Backport of 6770b7ecd208a0746f181e54202fb829460c6490 from master
| -rw-r--r-- | docs/topics/db/queries.txt | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index 7c1f50a87e..277978e842 100644 --- a/docs/topics/db/queries.txt +++ b/docs/topics/db/queries.txt @@ -545,8 +545,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"*. 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.exclude` calls. Everything inside a +:meth:`~django.db.models.query.QuerySet.filter` calls. Everything inside a single :meth:`~django.db.models.query.QuerySet.filter` call is applied simultaneously to filter out items matching all those requirements. Successive :meth:`~django.db.models.query.QuerySet.filter` calls further restrict the set @@ -580,14 +579,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 ``Blog`` items with each filter statement, not the ``Entry`` items. -All of this behavior also applies to -:meth:`~django.db.models.query.QuerySet.exclude`: all the conditions in a -single :meth:`~django.db.models.query.QuerySet.exclude` statement apply to a -single instance (if those conditions are talking about the same multi-valued -relation). Conditions in subsequent -:meth:`~django.db.models.query.QuerySet.filter` or -:meth:`~django.db.models.query.QuerySet.exclude` calls that refer to the same -relation may end up filtering on different linked objects. +.. note:: + + The behavior of :meth:`~django.db.models.query.QuerySet.filter` for queries + that span multi-value relationships, as described above, is not implemented + equivalently for :meth:`~django.db.models.query.QuerySet.exclude`. Instead, + the conditions in a single :meth:`~django.db.models.query.QuerySet.exclude` + call will not necessarily refer to the same item. + + 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: |
