Exemplo n.º 1
0
 def _prepare_pos_var(self, pos, method_name, valid_pos, valid_sorted_pos):
     if pos is None:
         if self.node_order_by:
             pos = 'sorted-sibling'
         else:
             pos = 'last-sibling'
     if pos not in valid_pos:
         raise InvalidPosition('Invalid relative position: %s' % (pos, ))
     if self.node_order_by and pos not in valid_sorted_pos:
         raise InvalidPosition(
             'Must use %s in %s when node_order_by is enabled' %
             (' or '.join(valid_sorted_pos), method_name))
     if pos in valid_sorted_pos and not self.node_order_by:
         raise MissingNodeOrderBy('Missing node_order_by attribute.')
     return pos
Exemplo n.º 2
0
 def _fix_add_sibling_opts(self, pos):
     "prepare the pos variable for the add_sibling method"
     if pos is None:
         if self.node_order_by:
             pos = 'sorted-sibling'
         else:
             pos = 'last-sibling'
     if pos not in ('first-sibling', 'left', 'right', 'last-sibling',
                    'sorted-sibling'):
         raise InvalidPosition('Invalid relative position: %s' % (pos, ))
     if self.node_order_by and pos != 'sorted-sibling':
         raise InvalidPosition('Must use %s in add_sibling when'
                               ' node_order_by is enabled' %
                               ('sorted-sibling', ))
     if pos == 'sorted-sibling' and not self.node_order_by:
         raise MissingNodeOrderBy('Missing node_order_by attribute.')
     return pos
Exemplo n.º 3
0
def move_language_tree_node(
    request, region_slug, language_tree_node_id, target_id, target_position
):
    """
    This action moves the given language tree node to the given position relative to the given target.

    :param request: The current request
    :type request: ~django.http.HttpResponse

    :param region_slug: The slug of the region which language tree should be modified
    :type region_slug: str

    :param language_tree_node_id: The id of the language tree node which should be moved
    :type language_tree_node_id: int

    :param target_id: The id of the target language tree node
    :type target_id: int

    :param target_position: The desired position (choices: :mod:`~integreat_cms.cms.constants.position`)
    :type target_position: str

    :return: A redirection to the language tree
    :rtype: ~django.http.HttpResponseRedirect
    """

    region = request.region
    language_tree_node = get_object_or_404(
        region.language_tree_nodes, id=language_tree_node_id
    )
    target = get_object_or_404(region.language_tree_nodes, id=target_id)

    try:
        if target.depth == 1 and target_position in [position.LEFT, position.RIGHT]:
            raise InvalidPosition(_("A region can only have one root language."))
        language_tree_node.move(target, target_position)
        # Call the save method on the (reloaded) node in order to trigger possible signal handlers etc.
        # (The move()-method executes raw sql which might cause problems if the instance isn't fetched again)
        language_tree_node = LanguageTreeNode.objects.get(id=language_tree_node_id)
        language_tree_node.save()
        messages.success(
            request,
            _('The language tree node "{}" was successfully moved.').format(
                language_tree_node.translated_name
            ),
        )
        logger.debug(
            "%r moved to %r of %r by %r",
            language_tree_node,
            target_position,
            target,
            request.user,
        )
    except (ValueError, InvalidPosition, InvalidMoveToDescendant) as e:
        messages.error(request, e)
        logger.exception(e)

    return redirect("language_tree", **{"region_slug": region_slug})
Exemplo n.º 4
0
    def move(self, target, pos=None):
        """
        Moves the current node and all it's descendants to a new position
        relative to another node.

        :param target: The target mode which determines the new position
        :type target: ~integreat_cms.cms.models.abstract_tree_node.AbstractTreeNode

        :param pos: The new position of the page relative to the target
                    (choices: :mod:`~integreat_cms.cms.constants.position`)
        :type pos: str

        :raises ~treebeard.exceptions.InvalidPosition: If the node is moved to another region
        """
        logger.debug("Moving %r to position %r of %r", self, pos, target)
        # Do not allow to move a node outside its region
        if self.region != target.region:
            # Allow moving as siblings of root nodes (because it's a separate tree)
            if not (target.is_root() and pos in [
                    position.LEFT,
                    position.RIGHT,
                    position.FIRST_SIBLING,
                    position.LAST_SIBLING,
            ]):
                raise InvalidPosition(
                    _('The node "{}" in region "{}" cannot be moved to "{}".').
                    format(self, self.region, target.region))
        # Moving a node can modify all other nodes via raw sql queries (which are not recognized by cachalot),
        # so we have to invalidate the whole model manually.
        invalidate_model(self.__class__)
        super().move(target=target, pos=pos)
        invalidate_model(self.__class__)

        # Reload 'self' because lft/rgt may have changed
        self.refresh_from_db()
        # Update parent to fix inconsistencies between tree fields
        new_parent = self.get_parent(update=True)
        logger.debug("Updating parent field from %r to %r", self.parent,
                     new_parent)
        self.parent = new_parent
        self.save()
Exemplo n.º 5
0
    def move(self, target, pos=None):
        """
        Extension to the treebeard 'move' method to ensure that
        Page will be places to allowed position.
        """

        # todo: maybe move it to the special admin method
        cpos = (
            'first-child',
            'last-child',
            'sorted-child',
        )
        spos = (
            'first-sibling',
            'left',
            'right',
            'last-sibling',
            'sorted-sibling',
        )
        page = self.specific
        if (pos in cpos and not page.can_move_to(target)) or (
                pos in spos and target.get_parent()
                and not page.can_move_to(target.get_parent())):
            raise InvalidPosition(
                'Can not move "%s" (%s) to %s (%s), '
                'allowed parent types are (%s).' % (
                    page,
                    type(page).__name__,
                    target,
                    target.specific_class.__name__,
                    ', '.join(i.__name__
                              for i in page.allowed_parent_page_models()),
                ))

        super().move(target, pos=pos)
        type(page).objects.get(id=page.id).save(is_moved=True)

        logger.info('Page moved: #%d "%s" to #%d: "%s" as "%s"', page.id,
                    page.title, target.id, target.title, pos)