Opened 13 years ago
Closed 11 years ago
#17424 closed Bug (fixed)
Using exclude on a queryset with an annotate field gives attribute error.
Reported by: | Owned by: | Łukasz Rekucki | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | asendecka@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Generating a MySQL query with an annotate
followed by an exclude
which follows two foreignkey relations results in:
AttributeError: 'NoneType' object has no attribute 'startswith'
To reproduce this, you can do the following:
Create a new project, set the backend to mysql
(and make a database), and create an app foo
with this models.py
:
from django.db import models class Model1(models.Model): pass class Model2(models.Model): model1 = models.ForeignKey(Model1) class Model3(models.Model): model2 = models.ForeignKey(Model2)
Put foo
in INSTALLED_APPS
, run syncdb
, and then run this in the django shell
from foo.models import * from django.db.models import Count print Model3.objects.annotate(bar=Count('id')).exclude(model2__model1__id=4).query
I'm running django 1.3.1 and python 2.6.7 on Mac OSX 10.7.1
This seems to be very similar to
https://code.djangoproject.com/ticket/12687
but, although that ticket is closed, the bug persists.
Attachments (3)
Change History (16)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Triage Stage: | Unreviewed → Accepted |
---|
by , 13 years ago
Attachment: | ticket17424.diff added |
---|
Patch without tests (done mostly by lrekucki, I was just helping)
comment:3 by , 13 years ago
Cc: | added |
---|
by , 13 years ago
Attachment: | ticket17424_with_tests.diff added |
---|
Previous patch with regression test added.
comment:4 by , 13 years ago
Has patch: | set |
---|
comment:5 by , 13 years ago
Owner: | changed from | to
---|
follow-up: 8 comment:7 by , 12 years ago
This is still an issue with 1.4.5 (not tested 1.5.x).
The patch provided fixes this exact problem, but is there any side effect I have to expect? Anybody verified this using tests?
And a last one: Will this patch be committed (or even backported to 1.4.x)?
Regards,
Marc
comment:8 by , 12 years ago
Replying to community@…:
The patch provided fixes this exact problem, but is there any side effect I have to expect? Anybody verified this using tests?
I'm pretty sure it has no side effects. At the time of writing it, the whole Django test suite passed.
And a last one: Will this patch be committed (or even backported to 1.4.x)?
I hope so. What this issue needs is someone to test it with master (patch, run the test suite) and if everything is OK, mark it as "Ready for check-in". Sadly, only regressions and security fixes go to maintenance branches, so this has a chance to be included in 1.6.
comment:10 by , 11 years ago
The issue seems to be fixed by refactoring in changeset:01b9c3d5193fe61b82ae8b26242a13fdec22f211. On master the condition in promote_joins()
still only checks if join_type
is not LOUTER
instead of explicitly checking for INNER
(which could result in promoting non-join to join). I would recommend adding an explicit assertion there or at least a comment why the author assumes that join_type
is not None
.
comment:11 by , 11 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Test looks good. Marking as RFC for @akaariai to take a look.
comment:12 by , 11 years ago
I am going to investigate the join_type issue. Maybe there are other cases where None could be promoted accidentally, like combining two querysets with |.
comment:13 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I have hit a very similar case. I cannot upload and attach files due to IT restrcitions where I am. However I can give you the following source:
managers.py
models.py
Example in the shell: