Improve validation errors for non-unique slug

- Informative validation: Tell users/devs which slug that is offending inside which URL hierarchy
pull/9718/head
Benjamin Bach 2021-11-24 01:10:07 +01:00 zatwierdzone przez LB (Ben Johnston)
rodzic 9e0bcce014
commit b6d35adb5f
7 zmienionych plików z 41 dodań i 9 usunięć

Wyświetl plik

@ -12,6 +12,7 @@ Changelog
* Make it possible to resize the page editors side panels (Sage Abdullah)
* Add ability to include `form_fields` as an APIField on `FormPage` (Sævar Öfjörð Magnússon, Suyash Singh, LB (Ben) Johnston)
* Ensure that images listings are more consistently aligned when there are fewer images uploaded (Theresa Okoro)
* Add more informative validation error messages for non-unique slugs within the admin interface and for programmatic page creation (Benjamin Bach)
* Fix: Make sure workflow timeline icons are visible in high-contrast mode (Loveth Omokaro)
* Fix: Ensure authentication forms (login, password reset) have a visible border in Windows high-contrast mode (Loveth Omokaro)
* Fix: Ensure visual consistency between buttons and links as buttons in Windows high-contrast mode (Albina Starykova)

Wyświetl plik

@ -22,6 +22,7 @@ depth: 1
* Make it possible to resize the page editors side panels (Sage Abdullah)
* Add ability to include [`form_fields` as an APIField](form_page_fields_api_field) on `FormPage` (Sævar Öfjörð Magnússon, Suyash Singh, LB (Ben) Johnston)
* Ensure that images listings are more consistently aligned when there are fewer images uploaded (Theresa Okoro)
* Add more informative validation error messages for non-unique slugs within the admin interface and for programmatic page creation (Benjamin Bach)
### Bug fixes

Wyświetl plik

@ -178,11 +178,16 @@ class WagtailAdminPageForm(WagtailAdminModelForm):
def clean(self):
cleaned_data = super().clean()
if "slug" in self.cleaned_data:
if not Page._slug_is_available(
cleaned_data["slug"], self.parent_page, self.instance
):
page_slug = cleaned_data["slug"]
if not Page._slug_is_available(page_slug, self.parent_page, self.instance):
self.add_error(
"slug", forms.ValidationError(_("This slug is already in use"))
"slug",
forms.ValidationError(
_(
"The slug '%(page_slug)s' is already in use in use within the parent page"
)
% {"page_slug": page_slug}
),
)
return cleaned_data

Wyświetl plik

@ -1379,7 +1379,14 @@ class TestCopyPageAction(AdminAPITestCase):
self.assertEqual(response.status_code, 400)
content = json.loads(response.content.decode("utf-8"))
self.assertEqual(content, {"slug": ["This slug is already in use"]})
self.assertEqual(
content,
{
"slug": [
"The slug 'events' is already in use in use within the parent page at '/'"
]
},
)
class TestConvertAliasPageAction(AdminAPITestCase):

Wyświetl plik

@ -713,7 +713,12 @@ class TestPageCreation(TestCase, WagtailTestUtils):
self.assertEqual(response.status_code, 200)
# Check that a form error was raised
self.assertFormError(response, "form", "slug", "This slug is already in use")
self.assertFormError(
response,
"form",
"slug",
"The slug 'hello-world' is already in use in use within the parent page",
)
# form should be marked as having unsaved changes for the purposes of the dirty-forms warning
self.assertContains(response, "alwaysDirty: true")

Wyświetl plik

@ -1281,7 +1281,12 @@ class TestPageEdit(TestCase, WagtailTestUtils):
self.assertEqual(response.status_code, 200)
# Check that a form error was raised
self.assertFormError(response, "form", "slug", "This slug is already in use")
self.assertFormError(
response,
"form",
"slug",
"The slug 'hello-world' is already in use in use within the parent page",
)
def test_preview_on_edit(self):
post_data = {

Wyświetl plik

@ -1098,8 +1098,16 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
def clean(self):
super().clean()
if not Page._slug_is_available(self.slug, self.get_parent(), self):
raise ValidationError({"slug": _("This slug is already in use")})
parent_page = self.get_parent()
if not Page._slug_is_available(self.slug, parent_page, self):
raise ValidationError(
{
"slug": _(
"The slug '%(page_slug)s' is already in use in use within the parent page at '%(parent_url_path)s'"
)
% {"page_slug": self.slug, "parent_url_path": parent_page.url}
}
)
def is_site_root(self):
"""