diff --git a/CHANGES.html b/CHANGES.html index f7d0b15..9eaf216 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -225,6 +225,17 @@ ul.auto-toc {
IMPORTANT: API Changed (import path changed), and Installation Note
The django_polymorphic source code has been restructured @@ -411,11 +422,11 @@ from polymorphic.models import PolymorphicModel, ...
Python 2.4 compatibility, contributed by Charles Leifer. Thanks!
Fix: The exception "...has no attribute 'sub_and_superclass_dict'" could be raised. (This occurred if a subclass defined __init__ @@ -429,7 +440,7 @@ Now it is possible to give a field the same name as the class
More about these additions in the docs: http://bserve.webhop.org/wiki/django_polymorphic/doc
Fixed ContentType related field accessor clash (an error emitted by model validation) by adding related_name to the ContentType @@ -475,7 +486,7 @@ ForeignKey. This happened if your polymorphc model used a ContentType ForeignKey. Thanks to Andrew Ingram.
Restructured django_polymorphic into a regular Django add-on application. This is needed for the management commands, and @@ -486,7 +497,7 @@ as well (and it makes sure the tests are always included).
("installation/testing") for more info.Added the polymorphic_dumpdata management command (github issue 4), for creating fixtures, this should be used instead of @@ -497,7 +508,7 @@ needs Django 1.2 (important as any polymorphic model uses ContentType).
IMPORTANT - database schema change (more info in change log).
I hope I got this change in early enough before anyone started
diff --git a/CHANGES.rst b/CHANGES.rst
index b35344f..da94d0d 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,6 +3,18 @@
Changelog
++++++++++
+2011-01-24 V1.0 Release Candidate 1
+===================================
+
+Bugfixes
+------------------------
+
+* Fixed GitHub issue 15 (query result incomplete with inheritance).
+ Thanks to John Debs for reporting and the test case.
+
+
+------------------------------------------------------------------
+
2010-11-11 V1.0 Beta 2
======================
diff --git a/polymorphic/base.py b/polymorphic/base.py
index f49306a..0e56199 100644
--- a/polymorphic/base.py
+++ b/polymorphic/base.py
@@ -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):
diff --git a/polymorphic/query.py b/polymorphic/query.py
index 1bb8b16..6f059dc 100644
--- a/polymorphic/query.py
+++ b/polymorphic/query.py
@@ -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
diff --git a/polymorphic/tests.py b/polymorphic/tests.py
index 4984968..7005799 100644
--- a/polymorphic/tests.py
+++ b/polymorphic/tests.py
@@ -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()
+[