Defer validation of required text fields in previews

pull/12987/head
Sage Abdullah 2025-03-17 21:25:00 +07:00 zatwierdzone przez Matt Westcott
rodzic 6b40a38346
commit 9eac93a565
4 zmienionych plików z 159 dodań i 7 usunięć

Wyświetl plik

@ -264,6 +264,53 @@ class TestPreview(WagtailTestUtils, TestCase):
self.assertContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_create_with_deferred_required_fields(self):
preview_url = reverse(
"wagtailadmin_pages:preview_on_add",
args=("tests", "eventpage", self.home_page.id),
)
preview_session_key = "wagtail-preview-tests-eventpage-{}".format(
self.home_page.id
)
self.assertNotIn(preview_session_key, self.client.session)
response = self.client.post(
preview_url,
{
"title": "Bare minimum",
"slug": "bare-minimum",
"carousel_items-TOTAL_FORMS": 0,
"carousel_items-INITIAL_FORMS": 0,
"speakers-TOTAL_FORMS": 0,
"speakers-INITIAL_FORMS": 0,
"related_links-TOTAL_FORMS": 0,
"related_links-INITIAL_FORMS": 0,
"head_counts-TOTAL_FORMS": 0,
"head_counts-INITIAL_FORMS": 0,
},
)
# Check the JSON response
self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
response.content.decode(),
{"is_valid": True, "is_available": True},
)
# Check the user can refresh the preview
preview_session_key = "wagtail-preview-tests-eventpage-{}".format(
self.home_page.id
)
self.assertIn(preview_session_key, self.client.session)
response = self.client.get(preview_url)
# Check the HTML response
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "tests/event_page.html")
self.assertContains(response, "Bare minimum")
def test_preview_on_edit_with_m2m_field(self):
preview_url = reverse(
"wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
@ -354,6 +401,45 @@ class TestPreview(WagtailTestUtils, TestCase):
self.assertContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_edit_with_deferred_required_fields(self):
preview_url = reverse(
"wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
)
response = self.client.post(
preview_url,
{
"title": "Bare minimum",
"slug": "bare-minimum",
"carousel_items-TOTAL_FORMS": 0,
"carousel_items-INITIAL_FORMS": 0,
"speakers-TOTAL_FORMS": 0,
"speakers-INITIAL_FORMS": 0,
"related_links-TOTAL_FORMS": 0,
"related_links-INITIAL_FORMS": 0,
"head_counts-TOTAL_FORMS": 0,
"head_counts-INITIAL_FORMS": 0,
},
)
# Check the JSON response
self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
response.content.decode(),
{"is_valid": True, "is_available": True},
)
# Check the user can refresh the preview
preview_session_key = f"wagtail-preview-{self.event_page.id}"
self.assertIn(preview_session_key, self.client.session)
response = self.client.get(preview_url)
# Check the HTML response
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "tests/event_page.html")
self.assertContains(response, "Bare minimum")
def test_preview_on_edit_expiry(self):
initial_datetime = timezone.now()
expiry_datetime = initial_datetime + datetime.timedelta(

Wyświetl plik

@ -11,6 +11,7 @@ from django.utils.functional import cached_property
from django.utils.translation import gettext
from django.views.generic import TemplateView, View
from wagtail.admin.forms.models import WagtailAdminModelForm
from wagtail.admin.panels import get_edit_handler
from wagtail.blocks.base import Block
from wagtail.models import PreviewableMixin, RevisionMixin
@ -77,10 +78,15 @@ class PreviewOnEdit(View):
post_data = ""
return QueryDict(post_data)
def validate_form(self, form):
if isinstance(form, WagtailAdminModelForm):
form.defer_required_fields()
return form.is_valid()
def post(self, request, *args, **kwargs):
self.remove_old_preview_data()
form = self.get_form(request.POST)
is_valid = form.is_valid()
is_valid = self.validate_form(form)
if is_valid:
# TODO: Handle request.FILES.
@ -89,7 +95,7 @@ class PreviewOnEdit(View):
else:
# Check previous data in session to determine preview availability
form = self.get_form(self._get_data_from_session())
is_available = form.is_valid()
is_available = self.validate_form(form)
return JsonResponse({"is_valid": is_valid, "is_available": is_available})
@ -104,7 +110,7 @@ class PreviewOnEdit(View):
def get(self, request, *args, **kwargs):
form = self.get_form(self._get_data_from_session())
if not form.is_valid():
if not self.validate_form(form):
return self.error_response()
form.save(commit=False)

Wyświetl plik

@ -95,9 +95,9 @@ class PreviewOnCreate(PreviewOnEdit):
def get_form(self, query_dict):
form = super().get_form(query_dict)
if form.is_valid():
if self.validate_form(form):
# Ensures our unsaved page has a suitable url.
form.instance.set_url_path(form.parent_page)
form.instance.full_clean()
form.instance.minimal_clean()
return form

Wyświetl plik

@ -65,7 +65,7 @@ class TestPreview(WagtailTestUtils, TestCase):
def test_preview_on_create_with_invalid_data(self):
self.assertNotIn(self.session_key_prefix, self.client.session)
response = self.client.post(self.preview_on_add_url, {"text": ""})
response = self.client.post(self.preview_on_add_url, {"categories": [999999]})
# Check the JSON response
self.assertEqual(response.status_code, 200)
@ -116,6 +116,36 @@ class TestPreview(WagtailTestUtils, TestCase):
self.assertContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_create_with_deferred_required_fields(self):
response = self.client.post(
self.preview_on_add_url,
{"categories": [self.holidays_category.id]},
)
# Check the JSON response
self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
response.content.decode(),
{"is_valid": True, "is_available": True},
)
# Check the user can refresh the preview
self.assertIn(self.session_key_prefix, self.client.session)
response = self.client.get(self.preview_on_add_url)
# Check the HTML response
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "tests/previewable_model.html")
# The text is empty
self.assertContains(response, "<title>(Default Preview)</title>", html=True)
self.assertContains(response, "<h1></h1>", html=True)
# The category is Holidays (only)
self.assertNotContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_edit_with_m2m_field(self):
response = self.client.post(self.preview_on_edit_url, self.post_data)
@ -150,7 +180,7 @@ class TestPreview(WagtailTestUtils, TestCase):
# Send an invalid update request
response = self.client.post(
self.preview_on_edit_url, {**self.post_data, "text": ""}
self.preview_on_edit_url, {**self.post_data, "categories": [999999]}
)
self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
@ -170,6 +200,36 @@ class TestPreview(WagtailTestUtils, TestCase):
self.assertContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_edit_with_deferred_required_fields(self):
response = self.client.post(
self.preview_on_edit_url,
{"categories": [self.holidays_category.id]},
)
# Check the JSON response
self.assertEqual(response.status_code, 200)
self.assertJSONEqual(
response.content.decode(),
{"is_valid": True, "is_available": True},
)
# Check the user can refresh the preview
self.assertIn(self.edit_session_key, self.client.session)
response = self.client.get(self.preview_on_edit_url)
# Check the HTML response
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "tests/previewable_model.html")
# The text is empty
self.assertContains(response, "<title>(Default Preview)</title>", html=True)
self.assertContains(response, "<h1></h1>", html=True)
# The category is Holidays (only)
self.assertNotContains(response, "<li>Parties</li>")
self.assertContains(response, "<li>Holidays</li>")
def test_preview_on_edit_expiry(self):
initial_datetime = timezone.now()
expiry_datetime = initial_datetime + datetime.timedelta(