Split EditView into get and create methods

pull/6331/head
Matt Westcott 2020-08-07 09:50:45 +01:00 zatwierdzone przez Matt Westcott
rodzic 8795ec94f6
commit bca74c41e2
1 zmienionych plików z 303 dodań i 294 usunięć

Wyświetl plik

@ -87,324 +87,333 @@ class EditView(TemplateResponseMixin, ContextMixin, View):
self.errors_debug = None
if self.request.method == 'GET':
if self.page_perms.user_has_lock():
if self.page.locked_at:
lock_message = format_html(_("<b>Page '{}' was locked</b> by <b>you</b> on <b>{}</b>."), self.page.get_admin_display_title(), self.page.locked_at.strftime("%d %b %Y %H:%M"))
else:
lock_message = format_html(_("<b>Page '{}' is locked</b> by <b>you</b>."), self.page.get_admin_display_title())
return super().dispatch(request)
def get(self, request):
if self.page_perms.user_has_lock():
if self.page.locked_at:
lock_message = format_html(_("<b>Page '{}' was locked</b> by <b>you</b> on <b>{}</b>."), self.page.get_admin_display_title(), self.page.locked_at.strftime("%d %b %Y %H:%M"))
else:
lock_message = format_html(_("<b>Page '{}' is locked</b> by <b>you</b>."), self.page.get_admin_display_title())
lock_message += format_html(
'<span class="buttons"><button class="button button-small button-secondary" data-locking-action="{}">{}</button></span>',
reverse('wagtailadmin_pages:unlock', args=(self.page.id,)),
_("Unlock")
)
messages.warning(self.request, lock_message, extra_tags='lock')
elif self.page.locked and self.page_perms.page_locked():
# the page can also be locked at a permissions level if in a workflow, on a task the user is not a reviewer for
# this should be indicated separately
if self.page.locked_by and self.page.locked_at:
lock_message = format_html(_("<b>Page '{}' was locked</b> by <b>{}</b> on <b>{}</b>."), self.page.get_admin_display_title(), str(self.page.locked_by), self.page.locked_at.strftime("%d %b %Y %H:%M"))
else:
# Page was probably locked with an old version of Wagtail, or a script
lock_message = format_html(_("<b>Page '{}' is locked</b>."), self.page.get_admin_display_title())
if self.page_perms.can_unlock():
lock_message += format_html(
'<span class="buttons"><button class="button button-small button-secondary" data-locking-action="{}">{}</button></span>',
reverse('wagtailadmin_pages:unlock', args=(self.page.id,)),
_("Unlock")
)
messages.warning(self.request, lock_message, extra_tags='lock')
messages.error(self.request, lock_message, extra_tags='lock')
elif self.page.locked and self.page_perms.page_locked():
# the page can also be locked at a permissions level if in a workflow, on a task the user is not a reviewer for
# this should be indicated separately
if self.page.locked_by and self.page.locked_at:
lock_message = format_html(_("<b>Page '{}' was locked</b> by <b>{}</b> on <b>{}</b>."), self.page.get_admin_display_title(), str(self.page.locked_by), self.page.locked_at.strftime("%d %b %Y %H:%M"))
if self.page.current_workflow_state:
workflow = self.workflow_state.workflow
task = self.workflow_state.current_task_state.task
if (
self.workflow_state.status != WorkflowState.STATUS_NEEDS_CHANGES
and task.specific.page_locked_for_user(self.page, self.request.user)
):
# Check for revisions still undergoing moderation and warn
if len(self.workflow_tasks) == 1:
# If only one task in workflow, show simple message
workflow_info = _("This page is currently awaiting moderation.")
else:
# Page was probably locked with an old version of Wagtail, or a script
lock_message = format_html(_("<b>Page '{}' is locked</b>."), self.page.get_admin_display_title())
if self.page_perms.can_unlock():
lock_message += format_html(
'<span class="buttons"><button class="button button-small button-secondary" data-locking-action="{}">{}</button></span>',
reverse('wagtailadmin_pages:unlock', args=(self.page.id,)),
_("Unlock")
workflow_info = format_html(
_("This page is awaiting <b>'{}'</b> in the <b>'{}'</b> workflow."),
task.name, workflow.name
)
messages.error(self.request, lock_message, extra_tags='lock')
messages.error(
self.request, mark_safe(workflow_info + " " + _("Only reviewers for this task can edit the page.")),
extra_tags="lock"
)
if self.page.current_workflow_state:
workflow = self.workflow_state.workflow
task = self.workflow_state.current_task_state.task
if (
self.workflow_state.status != WorkflowState.STATUS_NEEDS_CHANGES
and task.specific.page_locked_for_user(self.page, self.request.user)
):
# Check for revisions still undergoing moderation and warn
if len(self.workflow_tasks) == 1:
# If only one task in workflow, show simple message
workflow_info = _("This page is currently awaiting moderation.")
else:
workflow_info = format_html(
_("This page is awaiting <b>'{}'</b> in the <b>'{}'</b> workflow."),
task.name, workflow.name
)
messages.error(self.request, mark_safe(workflow_info + " " + _("Only reviewers for this task can edit the page.")),
extra_tags="lock")
self.form = self.form_class(instance=self.page, parent_page=self.parent)
self.has_unsaved_changes = False
self.edit_handler = self.edit_handler.bind_to(form=self.form)
self.add_legacy_moderation_warning()
self.page_for_status = self.get_page_for_status()
if self.request.method == 'POST':
self.form = self.form_class(
self.request.POST, self.request.FILES, instance=self.page, parent_page=self.parent
)
return self.render_to_response(self.get_context_data())
is_publishing = False
is_submitting = False
is_restarting_workflow = False
is_reverting = False
is_saving = False
is_cancelling_workflow = bool(self.request.POST.get('action-cancel-workflow')) and self.workflow_state and self.workflow_state.user_can_cancel(self.request.user)
if is_cancelling_workflow:
def post(self, request):
self.form = self.form_class(
self.request.POST, self.request.FILES, instance=self.page, parent_page=self.parent
)
is_publishing = False
is_submitting = False
is_restarting_workflow = False
is_reverting = False
is_saving = False
is_cancelling_workflow = bool(self.request.POST.get('action-cancel-workflow')) and self.workflow_state and self.workflow_state.user_can_cancel(self.request.user)
if is_cancelling_workflow:
self.workflow_state.cancel(user=self.request.user)
# do this here so even if the page is locked due to not having permissions, the original submitter can still cancel the workflow
if self.form.is_valid() and not self.page_perms.page_locked():
self.page = self.form.save(commit=False)
is_publishing = bool(self.request.POST.get('action-publish')) and self.page_perms.can_publish()
is_submitting = bool(self.request.POST.get('action-submit')) and self.page_perms.can_submit_for_moderation()
is_restarting_workflow = bool(self.request.POST.get('action-restart-workflow')) and self.page_perms.can_submit_for_moderation() and self.workflow_state and self.workflow_state.user_can_cancel(self.request.user)
is_reverting = bool(self.request.POST.get('revision'))
is_performing_workflow_action = bool(self.request.POST.get('action-workflow-action'))
if is_performing_workflow_action:
workflow_action = self.request.POST['workflow-action-name']
available_actions = self.page.current_workflow_task.get_actions(self.page, self.request.user)
available_action_names = [name for name, verbose_name, modal in available_actions]
if workflow_action not in available_action_names:
# prevent this action
is_performing_workflow_action = False
is_saving = True
has_content_changes = self.form.has_changed()
if is_restarting_workflow:
self.workflow_state.cancel(user=self.request.user)
# do this here so even if the page is locked due to not having permissions, the original submitter can still cancel the workflow
if self.form.is_valid() and not self.page_perms.page_locked():
self.page = self.form.save(commit=False)
# If a revision ID was passed in the form, get that revision so its
# date can be referenced in notification messages
if is_reverting:
previous_revision = get_object_or_404(self.page.revisions, id=self.request.POST.get('revision'))
is_publishing = bool(self.request.POST.get('action-publish')) and self.page_perms.can_publish()
is_submitting = bool(self.request.POST.get('action-submit')) and self.page_perms.can_submit_for_moderation()
is_restarting_workflow = bool(self.request.POST.get('action-restart-workflow')) and self.page_perms.can_submit_for_moderation() and self.workflow_state and self.workflow_state.user_can_cancel(self.request.user)
is_reverting = bool(self.request.POST.get('revision'))
if is_performing_workflow_action and not has_content_changes:
# don't save a new revision, as we're just going to update the page's
# workflow state with no content changes
revision = self.latest_revision
else:
# Save revision
revision = self.page.save_revision(
user=self.request.user,
log_action=True, # Always log the new revision on edit
previous_revision=(previous_revision if is_reverting else None)
)
is_performing_workflow_action = bool(self.request.POST.get('action-workflow-action'))
if is_performing_workflow_action:
workflow_action = self.request.POST['workflow-action-name']
available_actions = self.page.current_workflow_task.get_actions(self.page, self.request.user)
available_action_names = [name for name, verbose_name, modal in available_actions]
if workflow_action not in available_action_names:
# prevent this action
is_performing_workflow_action = False
# store submitted go_live_at for messaging below
go_live_at = self.page.go_live_at
is_saving = True
has_content_changes = self.form.has_changed()
if is_restarting_workflow:
self.workflow_state.cancel(user=self.request.user)
# If a revision ID was passed in the form, get that revision so its
# date can be referenced in notification messages
if is_reverting:
previous_revision = get_object_or_404(self.page.revisions, id=self.request.POST.get('revision'))
if is_performing_workflow_action and not has_content_changes:
# don't save a new revision, as we're just going to update the page's
# workflow state with no content changes
revision = self.latest_revision
else:
# Save revision
revision = self.page.save_revision(
user=self.request.user,
log_action=True, # Always log the new revision on edit
previous_revision=(previous_revision if is_reverting else None)
)
# store submitted go_live_at for messaging below
go_live_at = self.page.go_live_at
# Publish
if is_publishing:
for fn in hooks.get_hooks('before_publish_page'):
result = fn(self.request, self.page)
if hasattr(result, 'status_code'):
return result
revision.publish(
user=self.request.user,
changed=has_content_changes,
previous_revision=(previous_revision if is_reverting else None)
)
# Need to reload the page because the URL may have changed, and we
# need the up-to-date URL for the "View Live" button.
self.page = self.page.specific_class.objects.get(pk=self.page.pk)
for fn in hooks.get_hooks('after_publish_page'):
result = fn(self.request, self.page)
if hasattr(result, 'status_code'):
return result
# Submit
if is_submitting or is_restarting_workflow:
if self.workflow_state and self.workflow_state.status == WorkflowState.STATUS_NEEDS_CHANGES:
# If the workflow was in the needs changes state, resume the existing workflow on submission
self.workflow_state.resume(self.request.user)
else:
# Otherwise start a new workflow
workflow = self.page.get_workflow()
workflow.start(self.page, self.request.user)
if is_performing_workflow_action:
extra_workflow_data_json = self.request.POST.get('workflow-action-extra-data', '{}')
extra_workflow_data = json.loads(extra_workflow_data_json)
self.page.current_workflow_task.on_action(self.page.current_workflow_task_state, self.request.user, workflow_action, **extra_workflow_data)
# Notifications
# Publish
if is_publishing:
if go_live_at and go_live_at > timezone.now():
# Page has been scheduled for publishing in the future
if is_reverting:
message = _(
"Version from {0} of page '{1}' has been scheduled for publishing."
).format(
previous_revision.created_at.strftime("%d %b %Y %H:%M"),
self.page.get_admin_display_title()
)
else:
if self.page.live:
message = _(
"Page '{0}' is live and this version has been scheduled for publishing."
).format(
self.page.get_admin_display_title()
)
else:
message = _(
"Page '{0}' has been scheduled for publishing."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
else:
# Page is being published now
if is_reverting:
message = _(
"Version from {0} of page '{1}' has been published."
).format(
previous_revision.created_at.strftime("%d %b %Y %H:%M"),
self.page.get_admin_display_title()
)
else:
message = _(
"Page '{0}' has been published."
).format(
self.page.get_admin_display_title()
)
buttons = []
if self.page.url is not None:
buttons.append(messages.button(self.page.url, _('View live'), new_window=True))
buttons.append(messages.button(reverse('wagtailadmin_pages:edit', args=(self.page.id,)), _('Edit')))
messages.success(self.request, message, buttons=buttons)
elif is_submitting:
message = _(
"Page '{0}' has been submitted for moderation."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
elif is_cancelling_workflow:
message = _(
"Workflow on page '{0}' has been cancelled."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
('Edit')
)
])
elif is_restarting_workflow:
message = _(
"Workflow on page '{0}' has been restarted."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
elif is_reverting:
message = _(
"Page '{0}' has been replaced with version from {1}."
).format(
self.page.get_admin_display_title(),
previous_revision.created_at.strftime("%d %b %Y %H:%M")
)
messages.success(self.request, message)
elif is_saving:
message = _(
"Page '{0}' has been updated."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message)
if is_saving:
for fn in hooks.get_hooks('after_edit_page'):
for fn in hooks.get_hooks('before_publish_page'):
result = fn(self.request, self.page)
if hasattr(result, 'status_code'):
return result
if is_publishing or is_submitting or is_restarting_workflow or is_performing_workflow_action:
# we're done here - redirect back to the explorer
if self.next_url:
# redirect back to 'next' url if present
return redirect(self.next_url)
# redirect back to the explorer
return redirect('wagtailadmin_explore', self.page.get_parent().id)
else:
# Just saving - remain on edit page for further edits
target_url = reverse('wagtailadmin_pages:edit', args=[self.page.id])
if self.next_url:
# Ensure the 'next' url is passed through again if present
target_url += '?next=%s' % urlquote(self.next_url)
return redirect(target_url)
else:
if self.page_perms.page_locked():
messages.error(self.request, _("The page could not be saved as it is locked"))
else:
messages.validation_error(
self.request, _("The page could not be saved due to validation errors"), self.form
)
self.errors_debug = (
repr(self.form.errors)
+ repr([
(name, formset.errors)
for (name, formset) in self.form.formsets.items()
if formset.errors
])
revision.publish(
user=self.request.user,
changed=has_content_changes,
previous_revision=(previous_revision if is_reverting else None)
)
self.has_unsaved_changes = True
# Need to reload the page because the URL may have changed, and we
# need the up-to-date URL for the "View Live" button.
self.page = self.page.specific_class.objects.get(pk=self.page.pk)
for fn in hooks.get_hooks('after_publish_page'):
result = fn(self.request, self.page)
if hasattr(result, 'status_code'):
return result
# Submit
if is_submitting or is_restarting_workflow:
if self.workflow_state and self.workflow_state.status == WorkflowState.STATUS_NEEDS_CHANGES:
# If the workflow was in the needs changes state, resume the existing workflow on submission
self.workflow_state.resume(self.request.user)
else:
# Otherwise start a new workflow
workflow = self.page.get_workflow()
workflow.start(self.page, self.request.user)
if is_performing_workflow_action:
extra_workflow_data_json = self.request.POST.get('workflow-action-extra-data', '{}')
extra_workflow_data = json.loads(extra_workflow_data_json)
self.page.current_workflow_task.on_action(self.page.current_workflow_task_state, self.request.user, workflow_action, **extra_workflow_data)
# Notifications
if is_publishing:
if go_live_at and go_live_at > timezone.now():
# Page has been scheduled for publishing in the future
if is_reverting:
message = _(
"Version from {0} of page '{1}' has been scheduled for publishing."
).format(
previous_revision.created_at.strftime("%d %b %Y %H:%M"),
self.page.get_admin_display_title()
)
else:
if self.page.live:
message = _(
"Page '{0}' is live and this version has been scheduled for publishing."
).format(
self.page.get_admin_display_title()
)
else:
message = _(
"Page '{0}' has been scheduled for publishing."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
else:
# Page is being published now
if is_reverting:
message = _(
"Version from {0} of page '{1}' has been published."
).format(
previous_revision.created_at.strftime("%d %b %Y %H:%M"),
self.page.get_admin_display_title()
)
else:
message = _(
"Page '{0}' has been published."
).format(
self.page.get_admin_display_title()
)
buttons = []
if self.page.url is not None:
buttons.append(messages.button(self.page.url, _('View live'), new_window=True))
buttons.append(messages.button(reverse('wagtailadmin_pages:edit', args=(self.page.id,)), _('Edit')))
messages.success(self.request, message, buttons=buttons)
elif is_submitting:
message = _(
"Page '{0}' has been submitted for moderation."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
elif is_cancelling_workflow:
message = _(
"Workflow on page '{0}' has been cancelled."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
('Edit')
)
])
elif is_restarting_workflow:
message = _(
"Workflow on page '{0}' has been restarted."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message, buttons=[
messages.button(
reverse('wagtailadmin_pages:view_draft', args=(self.page.id,)),
_('View draft'),
new_window=True
),
messages.button(
reverse('wagtailadmin_pages:edit', args=(self.page.id,)),
_('Edit')
)
])
elif is_reverting:
message = _(
"Page '{0}' has been replaced with version from {1}."
).format(
self.page.get_admin_display_title(),
previous_revision.created_at.strftime("%d %b %Y %H:%M")
)
messages.success(self.request, message)
elif is_saving:
message = _(
"Page '{0}' has been updated."
).format(
self.page.get_admin_display_title()
)
messages.success(self.request, message)
if is_saving:
for fn in hooks.get_hooks('after_edit_page'):
result = fn(self.request, self.page)
if hasattr(result, 'status_code'):
return result
if is_publishing or is_submitting or is_restarting_workflow or is_performing_workflow_action:
# we're done here - redirect back to the explorer
if self.next_url:
# redirect back to 'next' url if present
return redirect(self.next_url)
# redirect back to the explorer
return redirect('wagtailadmin_explore', self.page.get_parent().id)
else:
# Just saving - remain on edit page for further edits
target_url = reverse('wagtailadmin_pages:edit', args=[self.page.id])
if self.next_url:
# Ensure the 'next' url is passed through again if present
target_url += '?next=%s' % urlquote(self.next_url)
return redirect(target_url)
else:
self.form = self.form_class(instance=self.page, parent_page=self.parent)
self.has_unsaved_changes = False
if self.page_perms.page_locked():
messages.error(self.request, _("The page could not be saved as it is locked"))
else:
messages.validation_error(
self.request, _("The page could not be saved due to validation errors"), self.form
)
self.errors_debug = (
repr(self.form.errors)
+ repr([
(name, formset.errors)
for (name, formset) in self.form.formsets.items()
if formset.errors
])
)
self.has_unsaved_changes = True
self.edit_handler = self.edit_handler.bind_to(form=self.form)
self.add_legacy_moderation_warning()