diff --git a/README.html b/README.html
index 08c4d95..32c5ccc 100644
--- a/README.html
+++ b/README.html
@@ -213,7 +213,6 @@ ul.auto-toc {
Polymorphic Models for Django
-
.
Quick Start, Docs, Contributing
diff --git a/README.rst b/README.rst
index 997566e..c017afa 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,6 @@
Polymorphic Models for Django
=============================
-.
Quick Start, Docs, Contributing
-------------------------------
diff --git a/polymorphic/base.py b/polymorphic/base.py
index 7210558..7bd0f3d 100644
--- a/polymorphic/base.py
+++ b/polymorphic/base.py
@@ -92,9 +92,11 @@ class PolymorphicModelBase(ModelBase):
for key, manager in base.__dict__.items():
if type(manager) == models.manager.ManagerDescriptor: manager = manager.manager
if not isinstance(manager, models.Manager): continue
+ if key in ['_base_manager']: continue # let Django handle _base_manager
if key in attrs: continue
if key in add_managers_keys: continue # manager with that name already added, skip
- if manager._inherited: continue # inherited managers have no significance, they are just copies
+ if manager._inherited: continue # inherited managers (on the bases) have no significance, they are just copies
+ #print >>sys.stderr,'##',self.__name__, key
if isinstance(manager, PolymorphicManager): # validate any inherited polymorphic managers
self.validate_model_manager(manager, self.__name__, key)
add_managers.append((base.__name__, key, manager))
diff --git a/polymorphic/polymorphic_model.py b/polymorphic/polymorphic_model.py
index b39cbec..29c7e3e 100644
--- a/polymorphic/polymorphic_model.py
+++ b/polymorphic/polymorphic_model.py
@@ -135,25 +135,24 @@ class PolymorphicModel(models.Model):
our appropriate base_objects manager.
"""
super(PolymorphicModel, self).__init__(*args, ** kwargs)
+
if self.__class__.polymorphic_super_sub_accessors_replaced: return
self.__class__.polymorphic_super_sub_accessors_replaced = True
- def create_accessor_function_for_model(model):
+ def create_accessor_function_for_model(model, accessor_name):
def accessor_function(self):
attr = model.base_objects.get(pk=self.pk)
return attr
return accessor_function
subclasses_and_superclasses_accessors = self.get_inheritance_relation_fields_and_models()
- #print '###',self.__class__.__name__,subclasses_and_superclasses_accessors
from django.db.models.fields.related import SingleRelatedObjectDescriptor, ReverseSingleRelatedObjectDescriptor
-
for name,model in subclasses_and_superclasses_accessors.iteritems():
orig_accessor = getattr(self.__class__, name, None)
if type(orig_accessor) in [SingleRelatedObjectDescriptor,ReverseSingleRelatedObjectDescriptor]:
- #print 'replacing',name, orig_accessor
- setattr(self.__class__, name, property(create_accessor_function_for_model(model)) )
+ #print >>sys.stderr, '---------- replacing',name, orig_accessor
+ setattr(self.__class__, name, property(create_accessor_function_for_model(model, name)) )
def get_inheritance_relation_fields_and_models(self):
"""helper function for __init__:
diff --git a/polymorphic/tests.py b/polymorphic/tests.py
index 8c0721b..bce835c 100644
--- a/polymorphic/tests.py
+++ b/polymorphic/tests.py
@@ -4,6 +4,7 @@
"""
import settings
+import sys
from django.test import TestCase
from django.db.models.query import QuerySet
@@ -29,6 +30,8 @@ class Model2B(Model2A):
field2 = models.CharField(max_length=10)
class Model2C(Model2B):
field3 = models.CharField(max_length=10)
+class Model2D(Model2C):
+ field4 = models.CharField(max_length=10)
class ModelShow1(ShowFieldType,PolymorphicModel):
field1 = models.CharField(max_length=10)
@@ -84,6 +87,13 @@ class RelationBC(RelationB):
class RelatingModel(models.Model):
many2many = models.ManyToManyField(Model2A)
+class One2OneRelatingModel(PolymorphicModel):
+ one2one = models.OneToOneField(Model2A)
+ field1 = models.CharField(max_length=10)
+
+class One2OneRelatingModelDerived(One2OneRelatingModel):
+ field2 = models.CharField(max_length=10)
+
class MyManager(PolymorphicManager):
def get_query_set(self):
return super(MyManager, self).get_query_set().order_by('-field1')
@@ -242,6 +252,9 @@ class testclass(TestCase):
entry1 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')
entry2 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')
+
+def show_base_manager(model):
+ print type(model._base_manager),model._base_manager.model
__test__ = {"doctest": """
#######################################################
@@ -249,19 +262,18 @@ __test__ = {"doctest": """
>>> settings.DEBUG=True
-#>>> get_version()
-#'1.0 rc1'
-
### simple inheritance
>>> o=Model2A.objects.create(field1='A1')
>>> o=Model2B.objects.create(field1='B1', field2='B2')
>>> o=Model2C.objects.create(field1='C1', field2='C2', field3='C3')
-
- [ ,
+>>> o=Model2D.objects.create(field1='D1', field2='D2', field3='D3', field4='D4')
+>>> Model2A.objects.all()
+[ ,
,
- ]
+ ,
+ ]
# manual get_real_instance()
>>> o=Model2A.base_objects.get(field1='C1')
@@ -269,6 +281,48 @@ __test__ = {"doctest": """
+### test inheritance pointers & _base_managers
+
+>>> show_base_manager(PlainA)
+
+>>> show_base_manager(PlainB)
+
+>>> show_base_manager(PlainC)
+
+>>> show_base_manager(Model2A)
+
+>>> show_base_manager(Model2B)
+
+>>> show_base_manager(Model2C)
+
+>>> show_base_manager(One2OneRelatingModel)
+
+>>> show_base_manager(One2OneRelatingModelDerived)
+
+
+>>> o=Model2A.base_objects.get(field1='C1')
+>>> o.model2b
+
+
+>>> o=Model2B.base_objects.get(field1='C1')
+>>> o.model2c
+
+
+
+### OneToOneField, test both directions for polymorphism
+
+>>> a=Model2A.base_objects.get(field1='C1')
+>>> b=One2OneRelatingModelDerived.objects.create(one2one=a, field1='f1', field2='f2')
+>>> b.one2one # this result is basically wrong, probably due to Django cacheing (we used base_objects), but should not be a problem
+
+>>> c=One2OneRelatingModelDerived.objects.get(field1='f1')
+>>> c.one2one
+
+
+>>> a.one2onerelatingmodel
+
+
+
### ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent, also with annotate()
>>> o=ModelShow1.objects.create(field1='abc')
@@ -315,15 +369,18 @@ __test__ = {"doctest": """
>>> Model2A.objects.instance_of(Model2B)
[ ,
- ]
+ ,
+ ]
>>> Model2A.objects.filter(instance_of=Model2B)
[ ,
- ]
+ ,
+ ]
>>> Model2A.objects.filter(Q(instance_of=Model2B))
[ ,
- ]
+ ,
+ ]
>>> Model2A.objects.not_instance_of(Model2B)
[ ]
@@ -345,7 +402,8 @@ __test__ = {"doctest": """
>>> oa.delete()
>>> Model2A.objects.all()
[ ,
- ]
+ ,
+ ]
### queryset combining
@@ -405,8 +463,8 @@ __test__ = {"doctest": """
>>> o=ModelWithMyManager.objects.create(field1='D1b', field4='D4b')
>>> ModelWithMyManager.objects.all()
-[ ,
- ]
+[ ,
+ ]
>>> type(ModelWithMyManager.objects)