Пример #1
0
    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()
Пример #2
0
 def test_split_tree_escape_odd(self):
     parts = tag_utils.split_tree_name("one/two///three/four")
     self.assertEqual(len(parts), 4)
     self.assertEqual(parts[0], "one")
     self.assertEqual(parts[1], "two/")
     self.assertEqual(parts[2], "three")
     self.assertEqual(parts[3], "four")
Пример #3
0
    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()
Пример #4
0
 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))
Пример #5
0
 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))
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    def validate_types(self, data):
        self.event_types_ids = []
        is_valid = True
        names = [
            name.strip() for name in self.initial_data['types'].split(',')
        ]
        names = list(set(names))
        names_to_create = []
        for name in names:
            clean_name = clean_tree_name(name)

            if clean_name != name:
                is_valid = False

            elif clean_name:

                obj = EventType.objects.filter(
                    Q(label=clean_name) | Q(name=clean_name)).first()
                if obj:
                    self.event_types_ids.append(obj.id)
                    self.event_types_ids += list(
                        obj.get_ancestors().values_list('id', flat=True))
                # create if not exist
                else:
                    parts = split_tree_name(clean_name)
                    if EventType.objects.filter(
                            label=parts[0],
                            level=1):  # ok -> '天災/颱風/自訂', error -> '颱風/自訂'
                        if len(parts) == 1:
                            clean_name = '其他/' + clean_name  # make '自訂' -> '其他/自訂'
                        names_to_create.append(clean_name)
                    else:
                        is_valid = False

        if not is_valid:
            raise ValidationError(
                _('This value does not match the required pattern'))

        for name in names_to_create:
            obj = EventType.objects.create(name=name)
            self.event_types_ids.append(obj.id)
            self.event_types_ids += list(obj.get_ancestors().values_list(
                'id', flat=True))
Пример #9
0
 def test_split_tree_escape_trailing(self):
     parts = tag_utils.split_tree_name("one/two//")
     self.assertEqual(len(parts), 2)
     self.assertEqual(parts[0], "one")
     self.assertEqual(parts[1], "two/")
Пример #10
0
 def test_split_tree_escape_leading(self):
     parts = tag_utils.split_tree_name("//one/two")
     self.assertEqual(len(parts), 2)
     self.assertEqual(parts[0], "/one")
     self.assertEqual(parts[1], "two")
Пример #11
0
 def test_split_tree_escape_even(self):
     parts = tag_utils.split_tree_name("one/two////dos/three")
     self.assertEqual(len(parts), 3)
     self.assertEqual(parts[0], "one")
     self.assertEqual(parts[1], "two//dos")
     self.assertEqual(parts[2], "three")
Пример #12
0
 def test_split_tree_three_spaced(self):
     parts = tag_utils.split_tree_name("  one  /  two  /  three  ")
     self.assertEqual(len(parts), 3)
     self.assertEqual(parts[0], "one")
     self.assertEqual(parts[1], "two")
     self.assertEqual(parts[2], "three")
Пример #13
0
 def test_split_tree_three_last_one_with_single_character(self):
     parts = tag_utils.split_tree_name("one/two/3")
     self.assertEqual(len(parts), 3)
     self.assertEqual(parts[0], "one")
     self.assertEqual(parts[1], "two")
     self.assertEqual(parts[2], "3")
Пример #14
0
 def test_split_tree_one_single_character(self):
     parts = tag_utils.split_tree_name("o")
     self.assertEqual(len(parts), 1)
     self.assertEqual(parts[0], "o")
Пример #15
0
 def test_split_tree_one(self):
     parts = tag_utils.split_tree_name("one")
     self.assertEqual(len(parts), 1)
     self.assertEqual(parts[0], "one")
Пример #16
0
 def test_split_tree_none(self):
     parts = tag_utils.split_tree_name("")
     self.assertEqual(len(parts), 0)