폼 빌더에서 리디렉션을 사용하여 이중 제출 방지 방법¶
폼 제출 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)