Fixed github issue 15 (query result incomplete with inheritance). Thanks to John Debs.
This commit is contained in:
@@ -76,6 +76,13 @@ class PolymorphicModelBase(ModelBase):
|
||||
# for __init__ function of this class (monkeypatching inheritance accessors)
|
||||
new_class.polymorphic_super_sub_accessors_replaced = False
|
||||
|
||||
# determine the name of the primary key field and store it into the class variable
|
||||
# polymorphic_primary_key_name (it is needed by query.py)
|
||||
for f in new_class._meta.fields:
|
||||
if f.primary_key and type(f)!=models.OneToOneField:
|
||||
new_class.polymorphic_primary_key_name=f.name
|
||||
break
|
||||
|
||||
return new_class
|
||||
|
||||
def get_inherited_managers(self, attrs):
|
||||
|
||||
@@ -161,7 +161,9 @@ class PolymorphicQuerySet(QuerySet):
|
||||
# We get different type(o.pk) in this case.
|
||||
# We work around this by using the real name of the field directly
|
||||
# for accessing the primary key of the the derived objects.
|
||||
pk_name = self.model._meta.pk.name
|
||||
# We might assume that self.model._meta.pk.name gives us the name of the primary key field,
|
||||
# but it doesn't. Therefore we use polymorphic_primary_key_name, which we set up in base.py.
|
||||
pk_name = self.model.polymorphic_primary_key_name
|
||||
|
||||
# For each model in "idlist_per_model" request its objects (the real model)
|
||||
# from the db and store them in results[].
|
||||
@@ -184,7 +186,7 @@ class PolymorphicQuerySet(QuerySet):
|
||||
for select_field_name in self.query.extra_select.keys():
|
||||
attr = getattr(base_result_objects_by_id[o_pk], select_field_name)
|
||||
setattr(o, select_field_name, attr)
|
||||
|
||||
|
||||
results[o_pk] = o
|
||||
|
||||
# re-create correct order and return result list
|
||||
|
||||
@@ -156,6 +156,14 @@ class InitTestModelSubclass(InitTestModel):
|
||||
def x(self):
|
||||
return 'XYZ'
|
||||
|
||||
# models from github issue
|
||||
class Top(PolymorphicModel):
|
||||
name = models.CharField(max_length=50)
|
||||
class Middle(Top):
|
||||
description = models.TextField()
|
||||
class Bottom(Middle):
|
||||
author = models.CharField(max_length=50)
|
||||
|
||||
|
||||
# UUID tests won't work with Django 1.1
|
||||
if not (django_VERSION[0] <= 1 and django_VERSION[1] <= 1):
|
||||
@@ -610,6 +618,20 @@ __test__ = {"doctest": """
|
||||
#>>> print 'DiamondXY fields 1: field_b "%s", field_x "%s", field_y "%s"' % (o.field_b, o.field_x, o.field_y)
|
||||
#DiamondXY fields 1: field_b "a", field_x "x", field_y "y"
|
||||
|
||||
# test for github issue
|
||||
>>> t = Top()
|
||||
>>> t.save()
|
||||
>>> m = Middle()
|
||||
>>> m.save()
|
||||
>>> b = Bottom()
|
||||
>>> b.save()
|
||||
>>> Top.objects.all()
|
||||
[<Top: Top object>, <Middle: Middle object>, <Bottom: Bottom object>]
|
||||
>>> Middle.objects.all()
|
||||
[<Middle: Middle object>, <Bottom: Bottom object>]
|
||||
>>> Bottom.objects.all()
|
||||
[<Bottom: Bottom object>]
|
||||
|
||||
|
||||
>>> settings.DEBUG=False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user