@@ -545,8 +545,7 @@ find entries linked to tags called *"music"* and *"bands"* or we might want an
545
545
entry that contains a tag with a name of *"music"* and a status of *"public"*.
546
546
547
547
To handle both of these situations, Django has a consistent way of processing
548
- :meth:`~django.db.models.query.QuerySet.filter` and
549
- :meth:`~django.db.models.query.QuerySet.exclude` calls. Everything inside a
548
+ :meth:`~django.db.models.query.QuerySet.filter` calls. Everything inside a
550
549
single :meth:`~django.db.models.query.QuerySet.filter` call is applied
551
550
simultaneously to filter out items matching all those requirements. Successive
552
551
: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
580
579
may not be the same as the entries in the first filter. We are filtering the
581
580
``Blog`` items with each filter statement, not the ``Entry`` items.
582
581
583
- All of this behavior also applies to
584
- :meth:`~django.db.models.query.QuerySet.exclude`: all the conditions in a
585
- single :meth:`~django.db.models.query.QuerySet.exclude` statement apply to a
586
- single instance (if those conditions are talking about the same multi-valued
587
- relation). Conditions in subsequent
588
- :meth:`~django.db.models.query.QuerySet.filter` or
589
- :meth:`~django.db.models.query.QuerySet.exclude` calls that refer to the same
590
- relation may end up filtering on different linked objects.
582
+ .. note::
583
+
584
+ The behavior of :meth:`~django.db.models.query.QuerySet.filter` for queries
585
+ that span multi-value relationships, as described above, is not implemented
586
+ equivalently for :meth:`~django.db.models.query.QuerySet.exclude`. Instead,
587
+ the conditions in a single :meth:`~django.db.models.query.QuerySet.exclude`
588
+ call will not necessarily refer to the same item.
589
+
590
+ For example, the following query would exclude blogs that contain *both*
591
+ entries with *"Lennon"* in the headline *and* entries published in 2008::
592
+
593
+ Blog.objects.exclude(
594
+ entry__headline__contains='Lennon',
595
+ entry__pub_date__year=2008,
596
+ )
597
+
598
+ However, unlike the behavior when using
599
+ :meth:`~django.db.models.query.QuerySet.filter`, this will not limit blogs
600
+ based on entries that satisfying both conditions. In order to do that, i.e.
601
+ to select all blogs that do not contain entries published with *"Lennon"*
602
+ that were published in 2008, you need to make two queries::
603
+
604
+ Blog.objects.exclude(
605
+ entry=Entry.objects.filter(
606
+ headline__contains='Lennon',
607
+ pub_date__year=2008,
608
+ ),
609
+ )
591
610
592
611
.. _using-f-expressions-in-filters:
593
612
0 commit comments