'InheritanceQuerySet.instance_of' and 'count' do not mix
ambroisie opened this issue · 0 comments
ambroisie commented
Problem
When trying to use InheritanceQuerySet.instance_of
to filter a queryset to only some sub-classes, and use queryset.count()
to get the count, instead I get an OperationalError
.
Environment
- Django Model Utils version: 4.2.0
- Django version: 4.0.3
- Python version: 3.10
Code examples
from django.db import models
from model_utils.managers import InheritanceManager
class Parent(models.Model):
objects = InheritanceManager()
field = models.CharField(max_length=50)
class ChildA(Parent):
field_chield_a = models.CharField(max_length=50)
class ChildB(Parent):
field_chield_b = models.CharField(max_length=50)
>>> for _ in range(3):
... ChildA()
... ChildB()
>>> from django.db import connection
>>> Parent.objects.instance_of(ChildA)
<InheritanceQuerySet [<ChildA: ChildA object (1)>, <ChildA: ChildA object (2)>, <ChildA: ChildA object (3)>]>
>>>Parent.objects.instance_of(ChildA).count()
Traceback (most recent call last):
File "<...>/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "<...>/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such column: playground_childa.parent_ptr_id
>>> from pprint import pprint
>>> pprint(connection.queries)
[{'sql': 'SELECT "playground_parent"."id", "playground_parent"."field", '
'"playground_childa"."parent_ptr_id", '
'"playground_childa"."field_chield_a" FROM "playground_parent" LEFT '
'OUTER JOIN "playground_childa" ON ("playground_parent"."id" = '
'"playground_childa"."parent_ptr_id") WHERE '
'(("playground_childa"."parent_ptr_id" IS NOT NULL)) LIMIT 21',
'time': '0.000'},
{'sql': 'SELECT COUNT(*) AS "__count" FROM "playground_parent" WHERE '
'(("playground_childa"."parent_ptr_id" IS NOT NULL))',
'time': '0.000'}]
As you can see, the query is missing the LEFT OUTER JOIN
directive when trying to use count
.