폼 빌더에서 리디렉션을 사용하여 이중 제출 방지 방법

폼 제출 HTTP 응답이 새 페이지로의 302 Found 임시 리디렉션인 경우가 일반적입니다. 기본적으로 wagtail.contrib.forms.models.FormPage 성공 응답은 이를 수행하지 않으므로 사용자가 성공 페이지를 새로 고쳐 정보를 다시 제출할 위험이 있습니다.

POST 응답에서 render_landing_page 콘텐츠를 렌더링하는 대신, FormPage 인스턴스의 route 를 자식 URL 경로로 리디렉션합니다. 콘텐츠는 동일한 폼 페이지의 관리자 내에서 계속 관리됩니다. 이 접근 방식은 추가 contrib 모듈 wagtail.contrib.routable_page 를 사용합니다.

대안적인 접근 방식은 routable_page 모듈이 필요 없는 완전히 다른 페이지로 리디렉션하는 것입니다. 사용자 지정 랜딩 페이지 리디렉션를 참조하십시오.

"wagtail.contrib.routable_page"INSTALLED_APPS 에 추가되었는지 확인하십시오. RoutablePageMixin 문서를 참조하십시오.

from django.shortcuts import redirect

from wagtail.contrib.forms.models import AbstractEmailForm
from wagtail.contrib.routable_page.models import RoutablePageMixin, path


class FormPage(RoutablePageMixin, AbstractEmailForm):

    # fields, content_panels, …

    @path("")
    def index_route(self, request, *args, **kwargs):
        """폼을 제공하고 POST 시 유효성을 검사합니다."""
        return super(AbstractEmailForm, self).serve(request, *args, **kwargs)

    def render_landing_page(self, request, form_submission, *args, **kwargs):
        """대신 self.thank_you 경로로 리디렉션합니다."""
        url = self.reverse_subpage("thank_you")
        # form_submission 인스턴스가 사용 가능한 경우, ID를 URL에 추가합니다.
        if form_submission:
            url += "?id=%s" % form_submission.id
        return redirect(self.url + url, permanent=False)

    @path("thank-you/")
    def thank_you(self, request):
        """리디렉션 후 슈퍼클래스의 랜딩 페이지를 반환합니다."""
        form_submission = None
        try:
            submission_id = int(request.GET["id"])
        except (KeyError, TypeError):
            pass
        else:
            submission_class = self.get_submission_class()
            try:
                form_submission = submission_class.objects.get(id=submission_id)
            except submission_class.DoesNotExist:
                pass

        return super().render_landing_page(request, form_submission)