Fixed github issue 15 (query result incomplete with inheritance). Thanks to John Debs.

This commit is contained in:
Bert Constantin
2011-01-24 16:37:38 +01:00
parent 3cc7d483c1
commit 2c47db8fcc
5 changed files with 67 additions and 13 deletions
+7
View File
@@ -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):
+4 -2
View File
@@ -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
+22
View File
@@ -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