mirror of
				https://github.com/django/django.git
				synced 2025-11-03 21:25:09 +00:00 
			
		
		
		
	Refs #14645 -- Documented bug with exclude() and multi-value relations
This commit is contained in:
		
							parent
							
								
									d94449f37a
								
							
						
					
					
						commit
						6770b7ecd2
					
				
					 1 changed files with 29 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -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"*.
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
``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:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue