def clean(self): cleaned_data = super().clean() if "slug" in self.cleaned_data: if not Page._slug_is_available(cleaned_data["slug"], self.parent_page, self.instance): self.add_error( "slug", forms.ValidationError(_("This slug is already in use"))) # Check scheduled publishing fields go_live_at = cleaned_data.get("go_live_at") expire_at = cleaned_data.get("expire_at") # Go live must be before expire if go_live_at and expire_at: if go_live_at > expire_at: msg = _("Go live date/time must be before expiry date/time") self.add_error("go_live_at", forms.ValidationError(msg)) self.add_error("expire_at", forms.ValidationError(msg)) # Expire at must be in the future if expire_at and expire_at < timezone.now(): self.add_error( "expire_at", forms.ValidationError( _("Expiry date/time must be in the future")), ) # Don't allow an existing first_published_at to be unset by clearing the field if ("first_published_at" in cleaned_data and not cleaned_data["first_published_at"]): del cleaned_data["first_published_at"] return cleaned_data
def move_confirm(request, page_to_move_id, destination_id): page_to_move = get_object_or_404(Page, id=page_to_move_id).specific # Needs .specific_deferred because the .get_admin_display_title method is called in template destination = get_object_or_404(Page, id=destination_id).specific_deferred if not Page._slug_is_available( page_to_move.slug, destination, page=page_to_move): messages.error( request, _("The slug '{0}' is already in use at the selected parent page. Make sure the slug is unique and try again" ).format(page_to_move.slug), ) return redirect( "wagtailadmin_pages:move_choose_destination", page_to_move.id, destination.id, ) for fn in hooks.get_hooks("before_move_page"): result = fn(request, page_to_move, destination) if hasattr(result, "status_code"): return result if request.method == "POST": # any invalid moves *should* be caught by the permission check in the action class, # so don't bother to catch InvalidMoveToDescendant action = MovePageAction(page_to_move, destination, pos="last-child", user=request.user) action.execute() messages.success( request, _("Page '{0}' moved.").format( page_to_move.get_admin_display_title()), buttons=[ messages.button( reverse("wagtailadmin_pages:edit", args=(page_to_move.id, )), _("Edit"), ) ], ) for fn in hooks.get_hooks("after_move_page"): result = fn(request, page_to_move) if hasattr(result, "status_code"): return result return redirect("wagtailadmin_explore", destination.id) return TemplateResponse( request, "wagtailadmin/pages/confirm_move.html", { "page_to_move": page_to_move, "destination": destination, }, )
def get_actionable_objects(self): objects, objects_without_access = super().get_actionable_objects() request = self.request if objects: self.target_parent_models = set( objects[0].specific_class.allowed_parent_page_models()) for obj in objects: self.target_parent_models.intersection_update( set(obj.specific_class.allowed_parent_page_models())) self.pages_to_move = [page.id for page in objects] if self.cleaned_form is None: if len(self.target_parent_models) == 0: return [], { **objects_without_access, "pages_without_common_parent_page": [{ "item": page, "can_edit": page.permissions_for_user( self.request.user).can_edit(), } for page in objects], } return objects, objects_without_access destination = self.cleaned_form.cleaned_data["chooser"] pages = [] pages_without_destination_access = [] pages_with_duplicate_slugs = [] for page in objects: if not page.permissions_for_user( request.user).can_move_to(destination): pages_without_destination_access.append(page) elif not Page._slug_is_available(page.slug, destination, page=page): pages_with_duplicate_slugs.append(page) else: pages.append(page) return pages, { **objects_without_access, "pages_without_destination_access": [{ "item": page, "can_edit": page.permissions_for_user(self.request.user).can_edit(), } for page in pages_without_destination_access], "pages_with_duplicate_slugs": [{ "item": page, "can_edit": page.permissions_for_user(self.request.user).can_edit(), } for page in pages_with_duplicate_slugs], }
def move_confirm(request, page_to_move_id, destination_id): page_to_move = get_object_or_404(Page, id=page_to_move_id).specific # Needs .specific_deferred because the .get_admin_display_title method is called in template destination = get_object_or_404(Page, id=destination_id).specific_deferred if not Page._slug_is_available( page_to_move.slug, destination, page=page_to_move): messages.error( request, _("The slug '{0}' is already in use at the selected parent page. Make sure the slug is unique and try again" ).format(page_to_move.slug), ) return redirect( "wagtailadmin_pages:move", page_to_move.id, ) for fn in hooks.get_hooks("before_move_page"): result = fn(request, page_to_move, destination) if hasattr(result, "status_code"): return result pages_to_move = {page_to_move} # The `construct_translated_pages_to_cascade_actions` hook returns translation and # alias pages when the action is set to "move" if getattr(settings, "WAGTAIL_I18N_ENABLED", False): for fn in hooks.get_hooks( "construct_translated_pages_to_cascade_actions"): fn_pages = fn([page_to_move], "move") if fn_pages and isinstance(fn_pages, dict): for additional_pages in fn_pages.values(): pages_to_move.update(additional_pages) pages_to_move = list(pages_to_move) if request.method == "POST": # any invalid moves *should* be caught by the permission check in the action # class, so don't bother to catch InvalidMoveToDescendant action = MovePageAction(page_to_move, destination, pos="last-child", user=request.user) action.execute() if getattr(settings, "WAGTAIL_I18N_ENABLED", False): # Move translation and alias pages if they have the same parent page. parent_page_translations = page_to_move.get_parent( ).get_translations() for translation in pages_to_move: if translation.get_parent() in parent_page_translations: # Move the translated or alias page to it's translated or # alias "destination" page. action = MovePageAction( translation, destination.get_translation(translation.locale), pos="last-child", user=request.user, ) action.execute() messages.success( request, _("Page '{0}' moved.").format( page_to_move.get_admin_display_title()), buttons=[ messages.button( reverse("wagtailadmin_pages:edit", args=(page_to_move.id, )), _("Edit"), ) ], ) for fn in hooks.get_hooks("after_move_page"): result = fn(request, page_to_move) if hasattr(result, "status_code"): return result return redirect("wagtailadmin_explore", destination.id) return TemplateResponse( request, "wagtailadmin/pages/confirm_move.html", { "page_to_move": page_to_move, "destination": destination, "translations_to_move_count": len([ translation.id for translation in pages_to_move if not translation.alias_of_id and translation.id != page_to_move.id ]), }, )