Skip to content

Commit 9500a21

Browse files
committed
fix error with .defer and child models that use the same parent
When using .defer on a PolymorphicQuerySet with multiple childs that subclass from the same polymorphic parent model yield an error like: >>> Base.objects.defer('ModelY___field_y') Traceback (most recent call last): ... FieldDoesNotExist: ModelX has no field named 'field_y'
1 parent 3af5db0 commit 9500a21

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

polymorphic/query.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from collections import defaultdict
99

1010
from django.contrib.contenttypes.models import ContentType
11+
from django.db.models import FieldDoesNotExist
1112
from django.db.models.query import ModelIterable, Q, QuerySet
1213
from django.utils import six
1314

@@ -392,6 +393,10 @@ class self.model, but as a class derived from self.model. We want to re-fetch
392393
# now a superclass of real_concrete_class. Thus it's
393394
# sufficient to just use the field name.
394395
translated_field_name = field.rpartition('___')[-1]
396+
try:
397+
real_concrete_class._meta.get_field(translated_field_name)
398+
except FieldDoesNotExist:
399+
continue
395400
else:
396401
raise
397402

polymorphic/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ModelShow2_plain(ModelShow1_plain):
8282

8383
class Base(ShowFieldType, PolymorphicModel):
8484
field_b = models.CharField(max_length=10)
85+
polymorphic_showfield_deferred = True
8586

8687

8788
class ModelX(Base):

polymorphic/tests/test_orm.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ def test_defer_fields(self):
178178
'<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField), '
179179
'deferred[field2,field3,field4,model2a_ptr_id,model2b_ptr_id]>')
180180

181+
ModelX.objects.create(field_b="A1", field_x="A2")
182+
ModelY.objects.create(field_b="B1", field_y="B2")
183+
184+
objects_deferred = Base.objects.defer('ModelY___field_y')
185+
self.assertEqual(repr(objects_deferred[0]),
186+
'<ModelX: id 1, field_b (CharField), field_x (CharField)>')
187+
self.assertEqual(repr(objects_deferred[1]),
188+
'<ModelY: id 2, field_b (CharField), field_y (CharField), deferred[field_y]>')
189+
190+
objects_only = Base.objects.only(
191+
'polymorphic_ctype', 'ModelY___field_y', 'ModelX___field_x',
192+
)
193+
self.assertEqual(repr(objects_only[0]),
194+
'<ModelX: id 1, field_b (CharField), field_x (CharField), deferred[field_b]>')
195+
self.assertEqual(repr(objects_only[1]),
196+
'<ModelY: id 2, field_b (CharField), field_y (CharField), deferred[field_b]>')
197+
181198
def test_defer_related_fields(self):
182199
self.create_model2abcd()
183200

0 commit comments

Comments
 (0)