From 0bca41410c31b338135275d7804121b06f27092a Mon Sep 17 00:00:00 2001 From: Dan Jacob Date: Thu, 7 Jan 2021 14:32:46 +0200 Subject: [PATCH] Ensure 303 returned on redirect --- CHANGES.md | 4 ++++ setup.py | 2 +- src/turbo_response/mixins.py | 16 ++++++++++++++-- src/turbo_response/tests/test_views.py | 3 +++ src/turbo_response/views.py | 5 +++-- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c9d39c1..59f2de6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changelog +## [0.0.16] - 2021-1-7 + +Ensure all form mixins/views return a 303 on redirect as per Turbo docs. + ## [0.0.15] - 2021-1-7 Removed protocol classes and mypy pre-commit requirement diff --git a/setup.py b/setup.py index fe35c74..239cf04 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ # Third Party Libraries from setuptools import setup -version = "0.0.15" +version = "0.0.16" setup( name="django-turbo-response", diff --git a/src/turbo_response/mixins.py b/src/turbo_response/mixins.py index 4e775b8..a138566 100644 --- a/src/turbo_response/mixins.py +++ b/src/turbo_response/mixins.py @@ -5,7 +5,7 @@ # Django from django import forms from django.core.exceptions import ImproperlyConfigured -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect # Local from .renderers import Action @@ -93,7 +93,7 @@ def render_turbo_stream_template_response( class TurboFormMixin: """Mixin for handling form validation. Ensures response - has 422 status on invalid""" + has 422 status on invalid and 303 on success""" def form_invalid(self, form: forms.Form) -> HttpResponse: return self.render_to_response( @@ -101,6 +101,18 @@ def form_invalid(self, form: forms.Form) -> HttpResponse: status=http.HTTPStatus.UNPROCESSABLE_ENTITY, ) + def form_valid(self, form: forms.Form) -> HttpResponse: + return HttpResponseRedirect( + self.get_success_url(), status=http.HTTPStatus.SEE_OTHER + ) + + +class TurboFormModelMixin(TurboFormMixin): + def form_valid(self, form): + """If the form is valid, save the associated model.""" + self.object = form.save() + return super().form_valid(form) + class TurboFrameResponseMixin: turbo_frame_dom_id = None diff --git a/src/turbo_response/tests/test_views.py b/src/turbo_response/tests/test_views.py index 9ac8c36..df8ecbb 100644 --- a/src/turbo_response/tests/test_views.py +++ b/src/turbo_response/tests/test_views.py @@ -104,6 +104,7 @@ def test_post_success(self, rf): req = rf.post("/", {"description": "ok"}) resp = self.MyView.as_view()(req) assert resp.url == "/done/" + assert resp.status_code == http.HTTPStatus.SEE_OTHER assert TodoItem.objects.count() == 1 @@ -130,6 +131,7 @@ def test_post_success(self, rf, todo): req = rf.post("/", {"description": "updated!"}) resp = self.MyView.as_view()(req, pk=todo.pk) assert resp.url == "/done/" + assert resp.status_code == http.HTTPStatus.SEE_OTHER todo.refresh_from_db() assert todo.description == "updated!" @@ -157,6 +159,7 @@ def test_post_with_validation_errors(self, rf): def test_post_success(self, rf): req = rf.post("/", {"description": "ok"}) resp = self.MyView.as_view()(req) + assert resp.status_code == http.HTTPStatus.SEE_OTHER assert resp.url == "/done/" diff --git a/src/turbo_response/views.py b/src/turbo_response/views.py index 3f2fa93..3ea39aa 100644 --- a/src/turbo_response/views.py +++ b/src/turbo_response/views.py @@ -16,6 +16,7 @@ from . import Action from .mixins import ( TurboFormMixin, + TurboFormModelMixin, TurboFrameResponseMixin, TurboFrameTemplateResponseMixin, TurboStreamResponseMixin, @@ -43,11 +44,11 @@ class TurboFormView(TurboFormMixin, FormView): ... -class TurboCreateView(TurboFormMixin, CreateView): +class TurboCreateView(TurboFormModelMixin, CreateView): ... -class TurboUpdateView(TurboFormMixin, UpdateView): +class TurboUpdateView(TurboFormModelMixin, UpdateView): ...