Defer validation of min_num constraints on InlinePanel when saving drafts

pull/12301/merge
Matt Westcott 2025-03-20 23:02:27 +00:00 zatwierdzone przez Matt Westcott
rodzic d0f28a1a69
commit 125a749a9a
4 zmienionych plików z 135 dodań i 3 usunięć

Wyświetl plik

@ -135,10 +135,11 @@ class WagtailAdminModelForm(
# keep hold of the `for_user` kwarg as well as passing it on to PermissionedForm
self.for_user = kwargs.get("for_user")
self.deferred_required_fields = []
self.deferred_formset_min_nums = {}
super().__init__(*args, **kwargs)
def defer_required_fields(self):
if self.deferred_required_fields:
if self.deferred_required_fields or self.deferred_formset_min_nums:
# defer_required_fields has already been called
return
@ -150,14 +151,20 @@ class WagtailAdminModelForm(
except KeyError:
pass
for formset in self.formsets.values():
for name, formset in self.formsets.items():
for form in formset:
form.defer_required_fields()
if formset.min_num is not None:
self.deferred_formset_min_nums[name] = formset.min_num
formset.min_num = 0
def restore_required_fields(self):
for formset in self.formsets.values():
for name, formset in self.formsets.items():
for form in formset:
form.restore_required_fields()
if name in self.deferred_formset_min_nums:
formset.min_num = self.deferred_formset_min_nums[name]
self.deferred_formset_min_nums = {}
for field_name in self.deferred_required_fields:
self.fields[field_name].required = True

Wyświetl plik

@ -18,6 +18,7 @@ from wagtail.models import (
)
from wagtail.signals import page_published
from wagtail.test.testapp.models import (
Advert,
BusinessChild,
BusinessIndex,
BusinessSubIndex,
@ -903,6 +904,89 @@ class TestPageCreation(WagtailTestUtils, TestCase):
self.assertEqual(response.status_code, 200)
self.assertContains(response, "This field is required.")
def test_can_create_page_with_less_than_min_inline_panels(self):
# min_num constraints on inline panels should not be enforced when saving as draft
post_data = nested_form_data(
{
"title": "Promotional page",
"slug": "promotional-page",
"advert_placements": inline_formset([]),
}
)
response = self.client.post(
reverse(
"wagtailadmin_pages:add",
args=("tests", "promotionalpage", self.root_page.id),
),
post_data,
)
# Find the page and check it
page = Page.objects.get(
path__startswith=self.root_page.path, slug="promotional-page"
).specific
# Should be redirected to edit page
self.assertRedirects(
response, reverse("wagtailadmin_pages:edit", args=(page.id,))
)
self.assertEqual(page.advert_placements.count(), 0)
self.assertFalse(page.live)
def test_cannot_publish_page_with_less_than_min_inline_panels(self):
# min_num constraints on inline panels should not be enforced when saving as draft
post_data = nested_form_data(
{
"title": "Promotional page",
"slug": "promotional-page",
"advert_placements": inline_formset([]),
"action-publish": "Publish",
}
)
response = self.client.post(
reverse(
"wagtailadmin_pages:add",
args=("tests", "promotionalpage", self.root_page.id),
),
post_data,
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Please submit at least 1 form.")
def test_can_publish_page_with_enough_inline_panels(self):
advert = Advert.objects.create(text="Red Bull gives you wings")
# min_num constraints on inline panels should not be enforced when saving as draft
post_data = nested_form_data(
{
"title": "Promotional page",
"slug": "promotional-page",
"advert_placements": inline_formset(
[
{
"advert": advert.id,
"colour": "red",
},
]
),
"action-publish": "Publish",
}
)
response = self.client.post(
reverse(
"wagtailadmin_pages:add",
args=("tests", "promotionalpage", self.root_page.id),
),
post_data,
)
self.assertRedirects(
response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
)
page = Page.objects.get(
path__startswith=self.root_page.path, slug="promotional-page"
).specific
self.assertTrue(page.live)
self.assertEqual(page.advert_placements.count(), 1)
def test_create_simplepage_scheduled(self):
go_live_at = timezone.now() + datetime.timedelta(days=1)
expire_at = timezone.now() + datetime.timedelta(days=2)

Wyświetl plik

@ -0,0 +1,35 @@
# Generated by Django 5.0.12 on 2025-03-20 22:31
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("tests", "0048_requireddatepage"),
("wagtailcore", "0094_alter_page_locale"),
]
operations = [
migrations.CreateModel(
name="PromotionalPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
],
options={
"abstract": False,
},
bases=("wagtailcore.page",),
),
]

Wyświetl plik

@ -1396,6 +1396,12 @@ class StandardIndex(Page):
promote_panels = []
class PromotionalPage(Page):
content_panels = Page.content_panels + [
InlinePanel("advert_placements", label="Adverts", min_num=1),
]
class StandardChild(Page):
pass