Creating an abstract model named InheritableTreeEntity which Node now descends from.
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Fri, 4 Jun 2010 04:26:59 +0000 (00:26 -0400)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Fri, 4 Jun 2010 04:26:59 +0000 (00:26 -0400)
In addition to consolidating the functionality common to trees of subclasses of a model,
this fixes a bug wherein attributes did not properly passthrough to children (similar to the bug that led to the implementation of a custom get_path method on Nodes).

models.py

index e32265d..cea36c2 100644 (file)
--- a/models.py
+++ b/models.py
@@ -195,9 +195,18 @@ class TreeEntity(TreeModel, Entity):
                abstract = True
 
 
-class Node(TreeEntity):
+class InheritableTreeEntity(TreeEntity):
        instance_type = models.ForeignKey(ContentType, editable=False)
        
+       def save(self, force_insert=False, force_update=False):
+               if not hasattr(self, 'instance_type_ptr'):
+                       self.instance_type = ContentType.objects.get_for_model(self.__class__)
+               super(InheritableTreeEntity, self).save(force_insert, force_update)
+       
+       @property
+       def instance(self):
+               return self.instance_type.get_object_for_this_type(id=self.id)
+       
        def get_path(self, pathsep='/', field='slug'):
                path = getattr(self.instance, field, '?')
                parent = self.parent
@@ -207,15 +216,23 @@ class Node(TreeEntity):
                return path
        path = property(get_path)
        
-       def save(self, force_insert=False, force_update=False):
-               if not hasattr(self, 'instance_type_ptr'):
-                       self.instance_type = ContentType.objects.get_for_model(self.__class__)
-               super(Node, self).save(force_insert, force_update)
-       
        @property
-       def instance(self):
-               return self.instance_type.get_object_for_this_type(id=self.id)
+       def attributes(self):
+               if self.parent:
+                       return QuerySetMapper(self.instance.attribute_set, passthrough=self.parent.instance.attributes)
+               return QuerySetMapper(self.instance.attribute_set)
+
+       @property
+       def relationships(self):
+               if self.parent:
+                       return QuerySetMapper(self.instance.relationship_set, passthrough=self.parent.instance.relationships)
+               return QuerySetMapper(self.instance.relationship_set)
        
+       class Meta:
+               abstract = True
+
+
+class Node(InheritableTreeEntity):
        accepts_subpath = False
        
        def render_to_response(self, request, path=None, subpath=None):