+ if mapper is None:
+ if self.parent:
+ mapper = TreeAttributeMapper
+ else:
+ mapper = AttributeMapper
+ return super(TreeEntity, self).get_attribute_mapper(mapper)
+ attributes = property(get_attribute_mapper)
+
+ def __unicode__(self):
+ return self.path
+
+ class Meta:
+ abstract = True
+
+
+class SlugTreeEntityManager(TreeEntityManager):
+ def get_with_path(self, path, root=None, absolute_result=True, pathsep='/', field='slug'):
+ return super(SlugTreeEntityManager, self).get_with_path(path, root, absolute_result, pathsep, field)
+
+
+class SlugTreeEntity(TreeEntity):
+ objects = SlugTreeEntityManager()
+ slug = models.SlugField(max_length=255)
+
+ def get_path(self, root=None, pathsep='/', field='slug'):
+ return super(SlugTreeEntity, self).get_path(root, pathsep, field)
+ path = property(get_path)
+
+ def clean(self):
+ if self.parent is None:
+ try:
+ self._default_manager.exclude(pk=self.pk).get(slug=self.slug, parent__isnull=True)
+ except self.DoesNotExist:
+ pass
+ else:
+ raise ValidationError(self.unique_error_message(self.__class__, ('parent', 'slug')))