Opened 12 years ago
Closed 12 years ago
#20250 closed Bug (fixed)
AttributeError when filtering annotated queryset with negated Q (via fk)
Reported by: | Owned by: | ||
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.4 |
Severity: | Normal | Keywords: | annotate AttributeError |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If these conditions are met:
- annotated queryset
- Q is filtering attribute related via foreign key
- Q is negation
Then AttributeError: 'NoneType' object has no attribute 'startswith'
exception is throwed. Stack looks the same as in 12687 (fixed), see below.
Note that *all* conditions above are necessary, code works if one omitted. Reproducible with Django 1.4.5, python 2.6.8.
Traceback (most recent call last): File "bug.py", line 16, in <module> print qst.query File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 167, in __str__ sql, params = self.sql_with_params() File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 175, in sql_with_params return self.get_compiler(DEFAULT_DB_ALIAS).as_sql() File "/usr/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 82, in as_sql where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 94, in as_sql sql, params = self.make_atom(child, qn, connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 154, in make_atom field_sql = self.sql_for_columns(lvalue, qn, connection) File "/usr/lib/python2.6/site-packages/django/db/models/sql/where.py", line 227, in sql_for_columns lhs = '%s.%s' % (qn(table_alias), qn(name)) File "/usr/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 49, in quote_name_unless_alias r = self.connection.ops.quote_name(name) File "/usr/lib/python2.6/site-packages/django/db/backends/sqlite3/base.py", line 145, in quote_name if name.startswith('"') and name.endswith('"'): AttributeError: 'NoneType' object has no attribute 'startswith'
Code snippet to reproduce the issue, bug.py:
from bug.models import * from django.db.models import Q,Count qobj=~Q(rtom3__x=0) #TOXIC #qobj=~Q(x=0) #OK #qobj=Q(rtom3__x=0) #OK qst = M1.objects.annotate(Count('m2')) #TOXIC #qst = M1.objects.all() #OK qst = qst.filter(qobj) #Gracefully returns [], no attempt to hit the database!!!! #print qst #Throws an exception! print qst.query
and models.py:
from django.db import models class M1(models.Model): rtom3 = models.ForeignKey("M3") x = models.IntegerField() class M2(models.Model): rtom1 = models.ForeignKey("M1") class M3(models.Model): x = models.IntegerField()
Change History (5)
comment:1 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:2 by , 12 years ago
Needs tests: | set |
---|---|
Resolution: | fixed |
Status: | closed → new |
Triage Stage: | Unreviewed → Accepted |
Reverting my fixed resolution, regression test should be added even if this already works in master.
comment:3 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 12 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
Pull request with a regression test: https://github.com/django/django/pull/1165
comment:5 by , 12 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
This seems to work on master. The results of the print qst.query are:
I haven't verified that the generated query is correct, but at least no errors are thrown.
Backpatching this to 1.4 will not happen as this isn't a critical bug (not a dataloss/security/regression/crash bug). I am marking this as fixed.