Example #1
0
    def reposition(self, site, right=None, parent=None):
        self.check_frozen()
        old_parent_node = self.node.get_parent()
        old_right_node = self.node.get_next_sibling()
        if right:
            if right.node.is_root():
                raise InvalidTreeMovement({'message': 'You can\'t move the root'})

            site.validate_relationship(right.get_parent(), self)
            self.node.move(right.node, pos='left')
        elif parent:
            site.validate_relationship(parent, self)
            self.node.move(parent.node, pos='last-child')
        else:
            assert right or parent

        try:
            # When moving, it's necessary to recheck compatibility for all of
            # our children. For example, this detects deep nesting of
            # un-nestable widgets.
            node = self._nodes.get()  # use a new, uncached node
            # use a prefetched tree
            node.prefetch_tree()
            node.content._recheck_children(site)
        except ParentChildRejection:
            # Backout. It'd be nice to rely on a transaction here and have this
            # happen automatically.
            if old_right_node:
                self.node.move(old_right_node, pos='left')
            else:
                self.node.move(old_parent_node, pos='last-child')
            raise
Example #2
0
    def delete(self, request, node_pk):
        node = get_object_or_404(Node, pk=node_pk)

        if not self.site.has_delete_permission(request, node.content):
            raise PermissionDenied(_("You don't have permission to delete this widget."))
        if not node.content.deletable:
            raise InvalidTreeMovement({'message': "You can't delete me"})

        try:
            node.content.delete()
            return self.render_as_node(None)
        except ProtectedError as e:
            raise ValidationError({'message': e.args[0]})
Example #3
0
    def put(self, request, node_pk):
        """
        If you put with a right_id, then your node will be placed immediately
        to the right of the node corresponding with the right_id.

        If you put with a parent_id, then your node will be placed as the
        first-child of the node corresponding with the parent_id.

        .. todo::
            put this in the model
        """
        node = get_object_or_404(Node, pk=node_pk)
        data = self.data()

        if not self.site.has_change_permission(request, node.content):
            raise PermissionDenied(
                _("You don't have permission to move this widget."))
        if not node.content.draggable:
            raise InvalidTreeMovement({'message': "You can't move me"})

        try:
            right = Node.objects.get(pk=extract_id(data['right_id']))
            node.content.reposition(self.site, right=right.content)
        except Node.DoesNotExist:
            try:
                parent = Node.objects.get(pk=extract_id(data['parent_id']))
                node.content.reposition(self.site, parent=parent.content)
            except Node.DoesNotExist:
                raise Http404

        # We have to refetch before returning because treebeard doesn't
        # update the in-memory instance, only the database, see
        # <https://tabo.pe/projects/django-treebeard/docs/tip/caveats.html#raw-queries>
        node = Node.objects.get(pk=node.pk)
        node.prefetch_tree()

        return self.render_as_node(node.to_json(self.site), status=200)