Added unittest for node_url templatetag. Fixed issues uncovered with unittests. Added...
[philo.git] / models / base.py
index 81e557f..ceeb81e 100644 (file)
@@ -3,14 +3,16 @@ from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes import generic
 from django.utils import simplejson as json
 from django.core.exceptions import ObjectDoesNotExist
+from philo.exceptions import AncestorDoesNotExist
 from philo.utils import ContentTypeRegistryLimiter
 from philo.signals import entity_class_prepared
+from philo.validators import json_validator
 from UserDict import DictMixin
 
 
 class Tag(models.Model):
-       name = models.CharField(max_length=250)
-       slug = models.SlugField(unique=True)
+       name = models.CharField(max_length=255)
+       slug = models.SlugField(max_length=255, unique=True)
        
        def __unicode__(self):
                return self.name
@@ -35,7 +37,7 @@ class Attribute(models.Model):
        entity_object_id = models.PositiveIntegerField(verbose_name='Entity ID')
        entity = generic.GenericForeignKey('entity_content_type', 'entity_object_id')
        key = models.CharField(max_length=255)
-       json_value = models.TextField(verbose_name='Value (JSON)', help_text='This value must be valid JSON.')
+       json_value = models.TextField(verbose_name='Value (JSON)', help_text='This value must be valid JSON.', validators=[json_validator])
        
        def get_value(self):
                return json.loads(self.json_value)
@@ -53,6 +55,7 @@ class Attribute(models.Model):
        
        class Meta:
                app_label = 'philo'
+               unique_together = ('key', 'entity_content_type', 'entity_object_id')
 
 
 value_content_type_limiter = ContentTypeRegistryLimiter()
@@ -81,6 +84,7 @@ class Relationship(models.Model):
        
        class Meta:
                app_label = 'philo'
+               unique_together = ('key', 'entity_content_type', 'entity_object_id')
 
 
 class QuerySetMapper(object, DictMixin):
@@ -238,7 +242,7 @@ class TreeManager(models.Manager):
 class TreeModel(models.Model):
        objects = TreeManager()
        parent = models.ForeignKey('self', related_name='children', null=True, blank=True)
-       slug = models.SlugField()
+       slug = models.SlugField(max_length=255)
        
        def has_ancestor(self, ancestor):
                parent = self
@@ -249,7 +253,9 @@ class TreeModel(models.Model):
                return False
        
        def get_path(self, root=None, pathsep='/', field='slug'):
-               if root is not None and self.has_ancestor(root):
+               if root is not None:
+                       if not self.has_ancestor(root):
+                               raise AncestorDoesNotExist(root)
                        path = ''
                        parent = self
                        while parent and parent != root:
@@ -273,7 +279,7 @@ class TreeModel(models.Model):
                abstract = True
 
 
-class TreeEntity(TreeModel, Entity):
+class TreeEntity(Entity, TreeModel):
        @property
        def attributes(self):
                if self.parent: