From f1f17ffa3849b0858ae6b6276ca2971eb3c5cbcb Mon Sep 17 00:00:00 2001 From: Sage Abdullah Date: Wed, 23 Nov 2022 11:24:28 +0000 Subject: [PATCH] Combine mixins into `CreateEditViewOptionalFeaturesMixin` --- wagtail/admin/views/generic/__init__.py | 3 +- wagtail/admin/views/generic/mixins.py | 137 +++++++----------------- wagtail/snippets/views/snippets.py | 4 +- 3 files changed, 43 insertions(+), 101 deletions(-) diff --git a/wagtail/admin/views/generic/__init__.py b/wagtail/admin/views/generic/__init__.py index 1a9119de4da1..5a3c8a17ad78 100644 --- a/wagtail/admin/views/generic/__init__.py +++ b/wagtail/admin/views/generic/__init__.py @@ -1,8 +1,7 @@ from .base import WagtailAdminTemplateMixin # noqa from .mixins import ( # noqa BeforeAfterHookMixin, - CreateViewOptionalFeaturesMixin, - EditViewOptionalFeaturesMixin, + CreateEditViewOptionalFeaturesMixin, HookResponseMixin, IndexViewOptionalFeaturesMixin, LocaleMixin, diff --git a/wagtail/admin/views/generic/mixins.py b/wagtail/admin/views/generic/mixins.py index 36ac7f21a6a8..e50c3b6bf67a 100644 --- a/wagtail/admin/views/generic/mixins.py +++ b/wagtail/admin/views/generic/mixins.py @@ -187,7 +187,9 @@ def _annotate_queryset_updated_at(self, queryset): return super()._annotate_queryset_updated_at(queryset) -class CreateViewOptionalFeaturesMixin: +class CreateEditViewOptionalFeaturesMixin: + view_name = "create" + def setup(self, request, *args, **kwargs): super().setup(request, *args, **kwargs) self.revision_enabled = self.model and issubclass(self.model, RevisionMixin) @@ -196,14 +198,30 @@ def setup(self, request, *args, **kwargs): def get_available_actions(self): return [*super().get_available_actions(), "publish"] - def get_success_message(self, instance): + def get_object(self, queryset=None): + if self.view_name == "create": + return None + self.live_object = super().get_object(queryset) + if self.draftstate_enabled: + return self.live_object.get_latest_revision_as_object() + return self.live_object + + def get_success_message(self, instance=None): + message = self.success_message if self.draftstate_enabled and self.action == "publish": - if instance.go_live_at and instance.go_live_at > timezone.now(): - return _("'%(object)s' created and scheduled for publishing.") % { - "object": instance - } - return _("'%(object)s' created and published.") % {"object": instance} - return super().get_success_message(instance) + if self.object.go_live_at and self.object.go_live_at > timezone.now(): + if self.view_name == "create": + message = _("'%(object)s' created and scheduled for publishing.") + else: + message = _("'%(object)s' updated and scheduled for publishing.") + if self.view_name == "create": + message = _("'%(object)s' created and published.") + else: + message = _("'%(object)s' updated and published.") + + if not message: + return None + return message.format(instance or self.object) def save_instance(self): """ @@ -211,97 +229,27 @@ def save_instance(self): and returns the new object. Override this to implement custom save logic. """ if self.draftstate_enabled: - # Make sure live is set to False when creating a new draft instance = self.form.save(commit=False) - instance.live = False - instance.save() - self.form.save_m2m() + + # If DraftStateMixin is applied, only save to the database in CreateView, + # and make sure the live field is set to False. + if self.view_name == "create": + instance.live = False + instance.save() + self.form.save_m2m() else: instance = self.form.save() - self.new_revision = None + self.has_content_changes = self.view_name == "create" or self.form.has_changed() # Save revision if the model inherits from RevisionMixin - if self.revision_enabled: - self.new_revision = instance.save_revision(user=self.request.user) - - log( - instance=instance, - action="wagtail.create", - revision=self.new_revision, - content_changed=True, - ) - - return instance - - def publish_action(self): - hook_response = self.run_hook("before_publish", self.request, self.object) - if hook_response is not None: - return hook_response - - self.new_revision.publish(user=self.request.user) - - hook_response = self.run_hook("after_publish", self.request, self.object) - if hook_response is not None: - return hook_response - - return None - - def form_valid(self, form): - self.form = form - with transaction.atomic(): - self.object = self.save_instance() - - if self.action == "publish" and self.draftstate_enabled: - response = self.publish_action() - if response is not None: - return response - - response = self.save_action() - - hook_response = self.run_after_hook() - if hook_response is not None: - return hook_response - - return response - - -class EditViewOptionalFeaturesMixin: - def setup(self, request, *args, **kwargs): - super().setup(request, *args, **kwargs) - self.revision_enabled = self.model and issubclass(self.model, RevisionMixin) - self.draftstate_enabled = self.model and issubclass(self.model, DraftStateMixin) - - def get_available_actions(self): - return [*super().get_available_actions(), "publish"] - - def get_object(self, queryset=None): - self.live_object = super().get_object(queryset) - if self.draftstate_enabled: - return self.live_object.get_latest_revision_as_object() - return self.live_object - - def save_instance(self): - """ - Called after the form is successfully validated - saves the object to the db. - Override this to implement custom save logic. - """ - commit = not self.draftstate_enabled - instance = self.form.save(commit=commit) self.new_revision = None - - self.has_content_changes = self.form.has_changed() - - # Save revision if the model inherits from RevisionMixin if self.revision_enabled: - self.new_revision = instance.save_revision( - user=self.request.user, - changed=self.has_content_changes, - ) + self.new_revision = instance.save_revision(user=self.request.user) log( instance=instance, - action="wagtail.edit", + action="wagtail.create" if self.view_name == "create" else "wagtail.edit", revision=self.new_revision, content_changed=self.has_content_changes, ) @@ -321,15 +269,6 @@ def publish_action(self): return None - def get_success_message(self): - if self.draftstate_enabled and self.action == "publish": - if self.object.go_live_at and self.object.go_live_at > timezone.now(): - return _("'%(object)s' updated and scheduled for publishing.") % { - "object": self.object - } - return _("'%(object)s' updated and published.") % {"object": self.object} - return super().get_success_message() - def form_valid(self, form): self.form = form with transaction.atomic(): @@ -349,6 +288,10 @@ def form_valid(self, form): return response def get_live_last_updated_info(self): + # Create view doesn't have last updated info + if self.view_name == "create": + return None + # DraftStateMixin is applied but object is not live if self.draftstate_enabled and not self.object.live: return None diff --git a/wagtail/snippets/views/snippets.py b/wagtail/snippets/views/snippets.py index f9174d819b35..0c07bd2a5a24 100644 --- a/wagtail/snippets/views/snippets.py +++ b/wagtail/snippets/views/snippets.py @@ -202,7 +202,7 @@ def get_template_names(self): return ["wagtailsnippets/snippets/type_index.html"] -class CreateView(generic.CreateViewOptionalFeaturesMixin, generic.CreateView): +class CreateView(generic.CreateEditViewOptionalFeaturesMixin, generic.CreateView): view_name = "create" preview_url_name = None permission_required = "add" @@ -302,7 +302,7 @@ def get_context_data(self, **kwargs): return context -class EditView(generic.EditViewOptionalFeaturesMixin, generic.EditView): +class EditView(generic.CreateEditViewOptionalFeaturesMixin, generic.EditView): view_name = "edit" history_url_name = None preview_url_name = None