Add docs and tests for snippets admin URL customisation

pull/10263/head
Sage Abdullah 2023-03-15 15:07:19 +00:00 zatwierdzone przez Matt Westcott
rodzic dc44e571c8
commit e6d920d435
5 zmienionych plików z 81 dodań i 0 usunięć

Wyświetl plik

@ -81,6 +81,8 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
.. autoattribute:: icon
.. autoattribute:: list_display
.. autoattribute:: admin_url_namespace
.. autoattribute:: base_url_path
.. autoattribute:: filterset_class
.. autoattribute:: index_view_class
.. autoattribute:: add_view_class
@ -97,4 +99,6 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
.. autoattribute:: preview_on_edit_view_class
.. autoattribute:: lock_view_class
.. autoattribute:: unlock_view_class
.. automethod:: get_admin_url_namespace
.. automethod:: get_admin_base_path
```

Wyświetl plik

@ -569,6 +569,8 @@ class MemberFilterSet(WagtailFilterSet):
You can define a {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.icon` attribute to specify the icon that is used across the admin for this snippet type. The `icon` needs to be [registered in the Wagtail icon library](../../advanced_topics/icons). If `icon` is not set, the default `"snippet"` icon is used.
The {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.admin_url_namespace` attribute can be set to use a custom URL namespace for the URL patterns of the views. If unset, it defaults to `wagtailsnippets_{app_label}_{model_name}`. Meanwhile, setting {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.base_url_path` allows you to customise the base URL path relative to the Wagtail admin URL. If unset, it defaults to `snippets/app_label/model_name`. If you need further customisations, you can also override the {meth}`~wagtail.snippets.views.snippets.SnippetViewSet.get_admin_url_namespace` and {meth}`~wagtail.snippets.views.snippets.SnippetViewSet.get_admin_base_path` methods to override the namespace and base URL path, respectively.
The {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_display` attribute can be set to specify the columns shown on the listing view. You can also add the ability to filter the listing view by defining a {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.filterset_class` attribute on a subclass of `SnippetViewSet`.
For example:
@ -584,6 +586,8 @@ from myapp.models import MemberFilterSet
class MemberViewSet(SnippetViewSet):
icon = "user"
list_display = ["name", "shirt_size", "get_shirt_size_display", UpdatedAtColumn()]
admin_url_namespace = "member_views"
base_url_path = "internal/member"
filterset_class = MemberFilterSet
```

Wyświetl plik

@ -3,6 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.urls import reverse
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.admin.panels import get_edit_handler
from wagtail.coreutils import get_dummy_request
from wagtail.models import Workflow, WorkflowContentType
@ -150,3 +151,68 @@ class TestSnippetChooserPanelWithIcon(WagtailTestUtils, TestCase):
for key in response.context.keys():
if "icon" in key:
self.assertNotIn("snippet", response.context[key])
class TestAdminURLs(WagtailTestUtils, TestCase):
def setUp(self):
self.user = self.login()
def test_default_url_namespace(self):
snippet = Advert.objects.create(text="foo")
viewset = snippet.snippet_viewset
# Accessed via the viewset
self.assertEqual(
viewset.get_admin_url_namespace(),
"wagtailsnippets_tests_advert",
)
# Accessed via the model
self.assertEqual(
snippet.get_admin_url_namespace(),
"wagtailsnippets_tests_advert",
)
# Get specific URL name
self.assertEqual(
viewset.get_url_name("edit"),
"wagtailsnippets_tests_advert:edit",
)
def test_default_admin_base_path(self):
snippet = Advert.objects.create(text="foo")
viewset = snippet.snippet_viewset
pk = quote(snippet.pk)
expected_url = f"/admin/snippets/tests/advert/edit/{pk}/"
# Accessed via the viewset
self.assertEqual(viewset.get_admin_base_path(), "snippets/tests/advert")
# Accessed via the model
self.assertEqual(snippet.get_admin_base_path(), "snippets/tests/advert")
# Get specific URL
self.assertEqual(reverse(viewset.get_url_name("edit"), args=[pk]), expected_url)
# Ensure AdminURLFinder returns the correct URL
url_finder = AdminURLFinder(self.user)
self.assertEqual(url_finder.get_edit_url(snippet), expected_url)
def test_custom_url_namespace(self):
snippet = FullFeaturedSnippet.objects.create(text="customised")
viewset = snippet.snippet_viewset
# Accessed via the viewset
self.assertEqual(viewset.get_admin_url_namespace(), "some_namespace")
# Accessed via the model
self.assertEqual(snippet.get_admin_url_namespace(), "some_namespace")
# Get specific URL name
self.assertEqual(viewset.get_url_name("edit"), "some_namespace:edit")
def test_custom_admin_base_path(self):
snippet = FullFeaturedSnippet.objects.create(text="customised")
viewset = snippet.snippet_viewset
pk = quote(snippet.pk)
expected_url = f"/admin/deep/within/the/admin/edit/{pk}/"
# Accessed via the viewset
self.assertEqual(viewset.get_admin_base_path(), "deep/within/the/admin")
# Accessed via the model
self.assertEqual(snippet.get_admin_base_path(), "deep/within/the/admin")
# Get specific URL
self.assertEqual(reverse(viewset.get_url_name("edit"), args=[pk]), expected_url)
# Ensure AdminURLFinder returns the correct URL
url_finder = AdminURLFinder(self.user)
self.assertEqual(url_finder.get_edit_url(snippet), expected_url)

Wyświetl plik

@ -995,11 +995,16 @@ class SnippetViewSet(ViewSet):
)
def get_admin_url_namespace(self):
"""Returns the URL namespace for the admin URLs for this model."""
if self.admin_url_namespace:
return self.admin_url_namespace
return f"wagtailsnippets_{self.app_label}_{self.model_name}"
def get_admin_base_path(self):
"""
Returns the base path for the admin URLs for this model.
The returned string must not begin or end with a slash.
"""
if self.base_url_path:
return self.base_url_path.strip().strip("/")
return f"snippets/{self.app_label}/{self.model_name}"

Wyświetl plik

@ -232,6 +232,8 @@ register_snippet(FilterableSnippet, viewset=FilterableSnippetViewSet)
class FullFeaturedSnippetViewSet(SnippetViewSet):
icon = "cog"
admin_url_namespace = "some_namespace"
base_url_path = "deep/within/the/admin"
register_snippet(FullFeaturedSnippet, viewset=FullFeaturedSnippetViewSet)