2
0
Эх сурвалжийг харах

Refactor create snippets view into class-based view (#8332)

sag᠎e 3 жил өмнө
parent
commit
ec70921e52

+ 10 - 10
wagtail/admin/views/generic/models.py

@@ -149,6 +149,13 @@ class CreateView(PermissionCheckedMixin, WagtailAdminTemplateMixin, BaseCreateVi
             return None
         return self.success_message.format(instance)
 
+    def get_success_buttons(self):
+        return [
+            messages.button(
+                reverse(self.edit_url_name, args=(self.object.id,)), _("Edit")
+            )
+        ]
+
     def get_error_message(self):
         if self.error_message is None:
             return None
@@ -173,23 +180,16 @@ class CreateView(PermissionCheckedMixin, WagtailAdminTemplateMixin, BaseCreateVi
             self.object = self.save_instance()
             log(instance=self.object, action="wagtail.create")
         success_message = self.get_success_message(self.object)
+        success_buttons = self.get_success_buttons()
         if success_message is not None:
-            messages.success(
-                self.request,
-                success_message,
-                buttons=[
-                    messages.button(
-                        reverse(self.edit_url_name, args=(self.object.id,)), _("Edit")
-                    )
-                ],
-            )
+            messages.success(self.request, success_message, buttons=success_buttons)
         return redirect(self.get_success_url())
 
     def form_invalid(self, form):
         self.form = form
         error_message = self.get_error_message()
         if error_message is not None:
-            messages.error(self.request, error_message)
+            messages.validation_error(self.request, error_message, form)
         return super().form_invalid(form)
 
 

+ 2 - 2
wagtail/snippets/templates/wagtailsnippets/snippets/create.html

@@ -3,9 +3,9 @@
 {% block titletag %}{% blocktrans trimmed with snippet_type_name=model_opts.verbose_name %}New  {{ snippet_type_name }}{% endblocktrans %}{% endblock %}
 {% block content %}
     {% trans "New" as new_str %}
-    {% include "wagtailadmin/shared/header_with_locale_selector.html" with title=new_str subtitle=model_opts.verbose_name icon="snippet" tabbed=1 merged=1 %}
+    {% include "wagtailadmin/shared/header_with_locale_selector.html" with title=new_str subtitle=model_opts.verbose_name icon="snippet" tabbed=1 merged=1 locale=locale translations=translations only %}
 
-    <form action="{% url 'wagtailsnippets:add' model_opts.app_label model_opts.model_name %}{% if locale %}?locale={{ locale.language_code }}{% endif %}" method="POST" novalidate{% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
+    <form action="{{ action_url }}" method="POST" novalidate{% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
         {% csrf_token %}
         {{ edit_handler.render_form_content }}
 

+ 5 - 1
wagtail/snippets/urls.py

@@ -28,7 +28,11 @@ urlpatterns = [
         snippets.ListView.as_view(results_only=True),
         name="list_results",
     ),
-    path("<slug:app_label>/<slug:model_name>/add/", snippets.create, name="add"),
+    path(
+        "<slug:app_label>/<slug:model_name>/add/",
+        snippets.Create.as_view(),
+        name="add",
+    ),
     path(
         "<slug:app_label>/<slug:model_name>/edit/<str:pk>/", snippets.edit, name="edit"
     ),

+ 150 - 93
wagtail/snippets/views/snippets.py

@@ -20,7 +20,7 @@ from wagtail.admin import messages
 from wagtail.admin.forms.search import SearchForm
 from wagtail.admin.panels import ObjectList, extract_panel_definitions_from_model_class
 from wagtail.admin.ui.tables import Column, DateColumn, UserColumn
-from wagtail.admin.views.generic.models import IndexView
+from wagtail.admin.views.generic import CreateView, IndexView
 from wagtail.log_actions import log
 from wagtail.log_actions import registry as log_registry
 from wagtail.models import Locale, TranslatableMixin
@@ -214,119 +214,176 @@ class ListView(TemplateView):
             return ["wagtailsnippets/snippets/type_index.html"]
 
 
-def create(request, app_label, model_name):
-    model = get_snippet_model_from_url_params(app_label, model_name)
+class Create(CreateView):
+    template_name = "wagtailsnippets/snippets/create.html"
+    error_message = _("The snippet could not be created due to errors.")
 
-    permission = get_permission_name("add", model)
-    if not request.user.has_perm(permission):
-        raise PermissionDenied
+    def _run_before_hooks(self):
+        for fn in hooks.get_hooks("before_create_snippet"):
+            result = fn(self.request, self.model)
+            if hasattr(result, "status_code"):
+                return result
+        return None
 
-    for fn in hooks.get_hooks("before_create_snippet"):
-        result = fn(request, model)
-        if hasattr(result, "status_code"):
-            return result
+    def _run_after_hooks(self):
+        for fn in hooks.get_hooks("after_create_snippet"):
+            result = fn(self.request, self.object)
+            if hasattr(result, "status_code"):
+                return result
+        return None
 
-    instance = model()
+    def setup(self, request, *args, **kwargs):
+        super().setup(request, *args, **kwargs)
 
-    # Set locale of the new instance
-    if issubclass(model, TranslatableMixin):
-        selected_locale = request.GET.get("locale")
-        if selected_locale:
-            instance.locale = get_object_or_404(Locale, language_code=selected_locale)
-        else:
-            instance.locale = Locale.get_default()
+        self.app_label = kwargs.get("app_label")
+        self.model_name = kwargs.get("model_name")
+        self.model = self._get_model()
+        self.locale = self._get_locale()
+        self.edit_handler = self._get_edit_handler()
 
-    # Make edit handler
-    edit_handler = get_snippet_edit_handler(model)
-    form_class = edit_handler.get_form_class()
+    def _get_model(self):
+        return get_snippet_model_from_url_params(self.app_label, self.model_name)
 
-    if request.method == "POST":
-        form = form_class(
-            request.POST, request.FILES, instance=instance, for_user=request.user
-        )
+    def _get_locale(self):
+        if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass(
+            self.model, TranslatableMixin
+        ):
+            selected_locale = self.request.GET.get("locale")
+            if selected_locale:
+                return get_object_or_404(Locale, language_code=selected_locale)
+            return Locale.get_default()
 
-        if form.is_valid():
-            with transaction.atomic():
-                form.save()
-                log(instance=instance, action="wagtail.create")
+        return None
 
-            messages.success(
-                request,
-                _("%(snippet_type)s '%(instance)s' created.")
-                % {
-                    "snippet_type": capfirst(model._meta.verbose_name),
-                    "instance": instance,
-                },
-                buttons=[
-                    messages.button(
-                        reverse(
-                            "wagtailsnippets:edit",
-                            args=(app_label, model_name, quote(instance.pk)),
-                        ),
-                        _("Edit"),
-                    )
-                ],
-            )
+    def _get_edit_handler(self):
+        return get_snippet_edit_handler(self.model)
 
-            for fn in hooks.get_hooks("after_create_snippet"):
-                result = fn(request, instance)
-                if hasattr(result, "status_code"):
-                    return result
+    def dispatch(self, request, *args, **kwargs):
+        permission = get_permission_name("add", self.model)
 
-            urlquery = ""
-            if (
-                isinstance(instance, TranslatableMixin)
-                and instance.locale is not Locale.get_default()
-            ):
-                urlquery = "?locale=" + instance.locale.language_code
+        if not request.user.has_perm(permission):
+            raise PermissionDenied
 
-            return redirect(
-                reverse("wagtailsnippets:list", args=[app_label, model_name]) + urlquery
-            )
-        else:
-            messages.validation_error(
-                request, _("The snippet could not be created due to errors."), form
+        hooks_result = self._run_before_hooks()
+        if hooks_result is not None:
+            return hooks_result
+
+        return super().dispatch(request, *args, **kwargs)
+
+    def get_add_url(self):
+        url = reverse("wagtailsnippets:add", args=[self.app_label, self.model_name])
+        if self.locale:
+            url += "?locale=" + self.locale.language_code
+        return url
+
+    def get_success_url(self):
+        urlquery = ""
+        if self.locale and self.object.locale is not Locale.get_default():
+            urlquery = "?locale=" + self.object.locale.language_code
+
+        return (
+            reverse("wagtailsnippets:list", args=[self.app_label, self.model_name])
+            + urlquery
+        )
+
+    def get_success_message(self, instance):
+        return _("%(snippet_type)s '%(instance)s' created.") % {
+            "snippet_type": capfirst(self.model._meta.verbose_name),
+            "instance": instance,
+        }
+
+    def get_success_buttons(self):
+        return [
+            messages.button(
+                reverse(
+                    "wagtailsnippets:edit",
+                    args=(
+                        self.app_label,
+                        self.model_name,
+                        quote(self.object.pk),
+                    ),
+                ),
+                _("Edit"),
             )
-    else:
-        form = form_class(instance=instance, for_user=request.user)
+        ]
 
-    edit_handler = edit_handler.get_bound_panel(
-        request=request, instance=instance, form=form
-    )
+    def _get_bound_panel(self, form):
+        return self.edit_handler.get_bound_panel(
+            request=self.request, instance=form.instance, form=form
+        )
 
-    action_menu = SnippetActionMenu(request, view="create", model=model)
+    def _get_action_menu(self):
+        return SnippetActionMenu(self.request, view="create", model=self.model)
 
-    context = {
-        "model_opts": model._meta,
-        "edit_handler": edit_handler,
-        "form": form,
-        "action_menu": action_menu,
-        "locale": None,
-        "translations": [],
-        "media": edit_handler.media + form.media + action_menu.media,
-    }
+    def _get_initial_form_instance(self):
+        instance = self.model()
+
+        # Set locale of the new instance
+        if self.locale:
+            instance.locale = self.locale
+
+        return instance
+
+    def get_form_class(self):
+        return self.edit_handler.get_form_class()
+
+    def get_form_kwargs(self):
+        return {
+            **super().get_form_kwargs(),
+            "instance": self._get_initial_form_instance(),
+            "for_user": self.request.user,
+        }
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+
+        form = context.get("form")
+        edit_handler = self._get_bound_panel(form)
+        action_menu = self._get_action_menu()
+        instance = form.instance
 
-    if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass(
-        model, TranslatableMixin
-    ):
         context.update(
             {
-                "locale": instance.locale,
-                "translations": [
-                    {
-                        "locale": locale,
-                        "url": reverse(
-                            "wagtailsnippets:add", args=[app_label, model_name]
-                        )
-                        + "?locale="
-                        + locale.language_code,
-                    }
-                    for locale in Locale.objects.all().exclude(id=instance.locale.id)
-                ],
+                "model_opts": self.model._meta,
+                "edit_handler": edit_handler,
+                "action_menu": action_menu,
+                "locale": None,
+                "translations": [],
+                "media": edit_handler.media + form.media + action_menu.media,
             }
         )
 
-    return TemplateResponse(request, "wagtailsnippets/snippets/create.html", context)
+        if self.locale:
+            context.update(
+                {
+                    "locale": instance.locale,
+                    "translations": [
+                        {
+                            "locale": locale,
+                            "url": reverse(
+                                "wagtailsnippets:add",
+                                args=[self.app_label, self.model_name],
+                            )
+                            + "?locale="
+                            + locale.language_code,
+                        }
+                        for locale in Locale.objects.all().exclude(
+                            id=instance.locale.id
+                        )
+                    ],
+                }
+            )
+
+        return context
+
+    def form_valid(self, form):
+        response = super().form_valid(form)
+
+        hooks_result = self._run_after_hooks()
+        if hooks_result is not None:
+            return hooks_result
+
+        return response
 
 
 def edit(request, app_label, model_name, pk):