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
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]})
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)