Q | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN
The following example shows that when ORing Q's Person is LEFT OUTER JOINed and House is erroneously INNER JOINed. At the same time ORing querysets works.
from django.db import models
from django.db.models import Q
class House(models.Model):
streetname = models.CharField(max_length=255)
class Person(models.Model):
home = models.ForeignKey(House)
class Rock(models.Model):
owner = models.ForeignKey(Person, null=True)
# with Q | Q
print Rock.objects.filter(Q(owner__isnull=True) | (Q(owner__home__streetname=''))).query
# with qs | qs
print (Rock.objects.filter(Q(owner__isnull=True)) | Rock.objects.filter(Q(owner__home__streetname=''))).query
This of course means that owner__
is_null=True won't work with Q's becaues of the INNER JOIN.
Tested with 1.0.4+, 1.2.3+ and 1.3 trunk@14864
Change History
(11)
Summary: |
(Q) | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN → Q | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN
|
Triage Stage: |
Unreviewed → Accepted
|
Severity: |
→ Normal
|
Type: |
→ Bug
|
Easy pickings: |
unset
|
Keywords: |
dceu2011 added
|
Owner: |
changed from nobody to Tomek Paczkowski
|
Status: |
new → assigned
|
UI/UX: |
unset
|
Cc: |
asendecka@… added
|
Has patch: |
set
|
Triage Stage: |
Accepted → Ready for checkin
|
Resolution: |
→ fixed
|
Status: |
assigned → closed
|
After countless hours of debugging, one line fix patch is ready. Test included. Done by me & ethlinn (Aleksandra Sendecka).