#34440: AND operator on queryset with joins gives wrong results
-------------------------------------+-------------------------------------
               Reporter:  Guillaume  |          Owner:  nobody
  LEBRETON                           |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  4.1
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:  orm and operato
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 From the doc https://docs.djangoproject.com/en/4.1/ref/models/querysets
 /#operators-that-return-new-querysets, 2 queryset with a single filter
 argument merged by a "&" operator is equivalent to queryset with a filter
 with 2 arguments.


 But with lookup with joins it do not seems to work that way:


 {{{
     # models.py
     ​
     class Person(models.Model):
         name = models.CharField(max_length=10, blank=True, null=True)
     ​
     ​
     class QuantitativeAttribute(models.Model):
         value = models.PositiveIntegerField()
         name = models.CharField(max_length=10)
         person = models.ForeignKey(Person,  on_delete=models.CASCADE)
     ​
     # tests.py
     ​
     class QuantitativeTestCase(TestCase):
     ​
         @classmethod
         def setUpTestData(cls):
     ​
             cls.p1 = Person.objects.create(name='p1')
             cls.p2 = Person.objects.create(name='p2')
     ​
             QuantitativeAttribute.objects.create(
                 person=cls.p1,
                 value=27,
                 name='age',
             )
     ​
             QuantitativeAttribute.objects.create(
                 person=cls.p1,
                 value=55,
                 name='concentration',
             )
     ​
             QuantitativeAttribute.objects.create(
                 person=cls.p2,
                 value=27,
                 name='concentration',
             )
     ​
             QuantitativeAttribute.objects.create(
                 person=cls.p2,
                 value=55,
                 name='age',
             )
     ​
         def test_combine_AND(self):
     ​
             expected_result = [
                 {'name': 'p1'}
             ]
     ​
             with self.subTest('single filter qs'):
                 qs =
 Person.objects.filter(quantitativeattribute__name='age',
 quantitativeattribute__value=27)
                 self.assertQuerysetEqual(qs.values('name'),
 expected_result)
     ​
             with self.subTest('combined AND filter qs'):
                 qs1 =
 Person.objects.filter(quantitativeattribute__name='age')
                 qs2 =
 Person.objects.filter(quantitativeattribute__value=27)
                 qs = qs1 & qs2
                 self.assertQuerysetEqual(qs.values('name'),
 expected_result)

 }}}

 Here, the first subtest,
 `Person.objects.filter(quantitativeattribute__name='age',
 quantitativeattribute__value=27)` gives the desired result.

 But the second subtest,
 `Person.objects.filter(quantitativeattribute__name='age') &
 Person.objects.filter(quantitativeattribute__value=27)` which according to
 the doc should be equal to the first subtest, is in fact equivalent to a
 chained filter query:
 
`Person.objects.filter(quantitativeattribute__name='age').filter(quantitativeattribute__value=27)`

 As it is explained here
 https://docs.djangoproject.com/en/4.1/topics/db/queries/#spanning-multi-
 valued-relationships in the docs, chained filters is not the query that i
 want.

 I tried to look for existing similar issue, i also went IRC #django but i
 did'nt find any answer yet.
 I think this ORM behavior is quite inconsistent, and at least it sould be
 stated in the doc for the "&" operator that the behavior may difer with
 joins

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34440>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018724acf0dc-39efa2a2-1192-4089-afdb-6fa065854c64-000000%40eu-central-1.amazonses.com.

Reply via email to