#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.