def save(self, *args, **kwargs): """ Set the parent and path cache """ # Make sure name is valid self.name = utils.clean_tree_name(self.name) # Find the parent, or create it if missing parts = utils.split_tree_name(self.name) old_parent = self.parent if len(parts) > 1: self.parent, created = self.__class__.objects.get_or_create( name=utils.join_tree_name(parts[:-1])) else: self.parent = None # Update other cache fields self.label = parts[-1] self.level = len(parts) # Save - super .save() method will set the path using _get_path() super(BaseTagTreeModel, self).save(*args, **kwargs) # If name has changed... if self._name != self.name: # Update child names for child in self.children.all(): child.name = utils.join_tree_name(parts + [child.label]) child.save() self._name = self.name # Notify parent that it may now be empty if old_parent: old_parent.update_count()
def save(self, *args, **kwargs): """ Set the parent and path cache """ # Make sure name is valid self.name = utils.clean_tree_name(self.name) # Find the parent, or create it if missing parts = utils.split_tree_name(self.name) old_parent = self.parent if len(parts) > 1: self.parent, created = self.__class__.objects.get_or_create( name=utils.join_tree_name(parts[:-1]) ) else: self.parent = None # Update other cache fields self.label = parts[-1] self.level = len(parts) # Save - super .save() method will set the path using _get_path() super(BaseTagTreeModel, self).save(*args, **kwargs) # If name has changed... if self._name != self.name: # Update child names for child in self.children.all(): child.name = utils.join_tree_name(parts + [child.label]) child.save() self._name = self.name # Notify parent that it may now be empty if old_parent: old_parent.update_count()
def with_ancestors(self): """ Add selected tags' ancestors to current queryset """ # Build list of all paths of all ancestors (and self) paths = [] for path in self.values_list('path', flat=True): parts = utils.split_tree_name(path) paths += [path] + [ utils.join_tree_name(parts[:i]) # Join parts up to i (misses last) for i in range(1, len(parts)) # Skip first (empty) ] return self._clean().filter(path__in=set(paths))
def get_ancestors(self): """ Get a queryset of ancestors for this tree node """ cls = self.__class__ if not self.parent: return cls.objects.none() # Get all ancestor paths from this path parts = utils.split_tree_name(self.path) paths = [ utils.join_tree_name(parts[:i]) # Join parts up to i (misses last) for i in range(1, len(parts)) # Skip first (empty) ] # Look up ancestors by path, already ordered by name for deepest last return cls.objects.filter(path__in=paths)
def test_join_tree_escape_trailing(self): name = tag_utils.join_tree_name(["one", "two/"]) self.assertEqual(name, "one/two//")
def test_join_tree_escape_leading(self): name = tag_utils.join_tree_name(["/one", "two"]) self.assertEqual(name, "//one/two")
def test_join_tree_escape_even(self): name = tag_utils.join_tree_name(["one", "two//dos", "three"]) self.assertEqual(name, "one/two////dos/three")
def test_join_tree_escape_odd(self): name = tag_utils.join_tree_name(["one/", "two"]) self.assertEqual(name, "one///two")
def test_join_tree_three(self): name = tag_utils.join_tree_name(["one", "two", "three"]) self.assertEqual(name, "one/two/three")
def test_join_tree_one(self): name = tag_utils.join_tree_name(["one"]) self.assertEqual(name, "one")