Added unique_together constraint to Attributes and Relationships.
[philo.git] / models / base.py
index 291fe70..87914be 100644 (file)
@@ -7,6 +7,28 @@ from philo.utils import ContentTypeRegistryLimiter
 from UserDict import DictMixin
 
 
+class Tag(models.Model):
+       name = models.CharField(max_length=250)
+       slug = models.SlugField(unique=True)
+       
+       def __unicode__(self):
+               return self.name
+       
+       class Meta:
+               app_label = 'philo'
+
+
+class Titled(models.Model):
+       title = models.CharField(max_length=255)
+       slug = models.SlugField(max_length=255)
+       
+       def __unicode__(self):
+               return self.title
+       
+       class Meta:
+               abstract = True
+
+
 class Attribute(models.Model):
        entity_content_type = models.ForeignKey(ContentType, verbose_name='Entity type')
        entity_object_id = models.PositiveIntegerField(verbose_name='Entity ID')
@@ -30,6 +52,7 @@ class Attribute(models.Model):
        
        class Meta:
                app_label = 'philo'
+               unique_together = ('key', 'entity_content_type', 'entity_object_id')
 
 
 value_content_type_limiter = ContentTypeRegistryLimiter()
@@ -58,23 +81,26 @@ class Relationship(models.Model):
        
        class Meta:
                app_label = 'philo'
+               unique_together = ('key', 'entity_content_type', 'entity_object_id')
 
 
 class QuerySetMapper(object, DictMixin):
        def __init__(self, queryset, passthrough=None):
                self.queryset = queryset
                self.passthrough = passthrough
+       
        def __getitem__(self, key):
                try:
                        return self.queryset.get(key__exact=key).value
                except ObjectDoesNotExist:
-                       if self.passthrough:
+                       if self.passthrough is not None:
                                return self.passthrough.__getitem__(key)
                        raise KeyError
+       
        def keys(self):
                keys = set(self.queryset.values_list('key', flat=True).distinct())
-               if self.passthrough:
-                       keys += set(self.passthrough.keys())
+               if self.passthrough is not None:
+                       keys |= set(self.passthrough.keys())
                return list(keys)
 
 
@@ -92,7 +118,6 @@ class Entity(models.Model):
        
        class Meta:
                abstract = True
-               app_label = 'philo'
 
 
 class TreeManager(models.Manager):
@@ -136,13 +161,29 @@ class TreeModel(models.Model):
        parent = models.ForeignKey('self', related_name='children', null=True, blank=True)
        slug = models.SlugField()
        
-       def get_path(self, pathsep='/', field='slug'):
-               path = getattr(self, field, '?')
-               parent = self.parent
+       def has_ancestor(self, ancestor):
+               parent = self
                while parent:
-                       path = getattr(parent, field, '?') + pathsep + path
+                       if parent == ancestor:
+                               return True
                        parent = parent.parent
-               return path
+               return False
+       
+       def get_path(self, root=None, pathsep='/', field='slug'):
+               if root is not None and self.has_ancestor(root):
+                       path = ''
+                       parent = self
+                       while parent and parent != root:
+                               path = getattr(parent, field, '?') + pathsep + path
+                               parent = parent.parent
+                       return path
+               else:
+                       path = getattr(self, field, '?')
+                       parent = self.parent
+                       while parent and parent != root:
+                               path = getattr(parent, field, '?') + pathsep + path
+                               parent = parent.parent
+                       return path
        path = property(get_path)
        
        def __unicode__(self):
@@ -151,7 +192,6 @@ class TreeModel(models.Model):
        class Meta:
                unique_together = (('parent', 'slug'),)
                abstract = True
-               app_label = 'philo'
 
 
 class TreeEntity(TreeModel, Entity):
@@ -168,5 +208,4 @@ class TreeEntity(TreeModel, Entity):
                return super(TreeEntity, self).relationships
        
        class Meta:
-               abstract = True
-               app_label = 'philo'
\ No newline at end of file
+               abstract = True
\ No newline at end of file