kopia lustrzana https://github.com/wagtail/wagtail
Allow admin URL customisation for snippet chooser views via SnippetViewSet
rodzic
9f070f6262
commit
b713a1753e
|
@ -83,6 +83,8 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
|
|||
.. autoattribute:: list_display
|
||||
.. autoattribute:: admin_url_namespace
|
||||
.. autoattribute:: base_url_path
|
||||
.. autoattribute:: chooser_admin_url_namespace
|
||||
.. autoattribute:: chooser_base_url_path
|
||||
.. autoattribute:: filterset_class
|
||||
.. autoattribute:: index_view_class
|
||||
.. autoattribute:: add_view_class
|
||||
|
@ -101,4 +103,6 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
|
|||
.. autoattribute:: unlock_view_class
|
||||
.. automethod:: get_admin_url_namespace
|
||||
.. automethod:: get_admin_base_path
|
||||
.. automethod:: get_chooser_admin_url_namespace
|
||||
.. automethod:: get_chooser_admin_base_path
|
||||
```
|
||||
|
|
|
@ -571,6 +571,8 @@ You can define a {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.icon` at
|
|||
|
||||
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.
|
||||
|
||||
Similar URL customisations are also possible for the snippet chooser views through {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.chooser_admin_url_namespace`, {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.chooser_base_url_path`, {meth}`~wagtail.snippets.views.snippets.SnippetViewSet.get_chooser_admin_url_namespace`, and {meth}`~wagtail.snippets.views.snippets.SnippetViewSet.get_chooser_admin_base_path`.
|
||||
|
||||
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:
|
||||
|
|
|
@ -139,9 +139,8 @@ class TestSnippetChooserPanelWithIcon(WagtailTestUtils, TestCase):
|
|||
self.assertNotIn("icon-snippet", field_html)
|
||||
|
||||
def test_chooser_popup(self):
|
||||
response = self.client.get(
|
||||
reverse("wagtailsnippetchoosers_tests_fullfeaturedsnippet:choose")
|
||||
)
|
||||
chooser_viewset = FullFeaturedSnippet.snippet_viewset.chooser_viewset
|
||||
response = self.client.get(reverse(chooser_viewset.get_url_name("choose")))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context["header_icon"], "cog")
|
||||
self.assertContains(response, "icon icon-cog", count=1)
|
||||
|
@ -175,12 +174,23 @@ class TestAdminURLs(WagtailTestUtils, TestCase):
|
|||
viewset.get_url_name("edit"),
|
||||
"wagtailsnippets_tests_advert:edit",
|
||||
)
|
||||
# Chooser namespace
|
||||
self.assertEqual(
|
||||
viewset.get_chooser_admin_url_namespace(),
|
||||
"wagtailsnippetchoosers_tests_advert",
|
||||
)
|
||||
# Get specific chooser URL name
|
||||
self.assertEqual(
|
||||
viewset.chooser_viewset.get_url_name("choose"),
|
||||
"wagtailsnippetchoosers_tests_advert:choose",
|
||||
)
|
||||
|
||||
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}/"
|
||||
expected_choose_url = "/admin/snippets/choose/tests/advert/"
|
||||
|
||||
# Accessed via the viewset
|
||||
self.assertEqual(viewset.get_admin_base_path(), "snippets/tests/advert")
|
||||
|
@ -191,6 +201,16 @@ class TestAdminURLs(WagtailTestUtils, TestCase):
|
|||
# Ensure AdminURLFinder returns the correct URL
|
||||
url_finder = AdminURLFinder(self.user)
|
||||
self.assertEqual(url_finder.get_edit_url(snippet), expected_url)
|
||||
# Chooser base path
|
||||
self.assertEqual(
|
||||
viewset.get_chooser_admin_base_path(),
|
||||
"snippets/choose/tests/advert",
|
||||
)
|
||||
# Get specific chooser URL
|
||||
self.assertEqual(
|
||||
reverse(viewset.chooser_viewset.get_url_name("choose")),
|
||||
expected_choose_url,
|
||||
)
|
||||
|
||||
def test_custom_url_namespace(self):
|
||||
snippet = FullFeaturedSnippet.objects.create(text="customised")
|
||||
|
@ -201,12 +221,23 @@ class TestAdminURLs(WagtailTestUtils, TestCase):
|
|||
self.assertEqual(snippet.get_admin_url_namespace(), "some_namespace")
|
||||
# Get specific URL name
|
||||
self.assertEqual(viewset.get_url_name("edit"), "some_namespace:edit")
|
||||
# Chooser namespace
|
||||
self.assertEqual(
|
||||
viewset.get_chooser_admin_url_namespace(),
|
||||
"my_chooser_namespace",
|
||||
)
|
||||
# Get specific chooser URL name
|
||||
self.assertEqual(
|
||||
viewset.chooser_viewset.get_url_name("choose"),
|
||||
"my_chooser_namespace:choose",
|
||||
)
|
||||
|
||||
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}/"
|
||||
expected_choose_url = "/admin/choose/wisely/"
|
||||
# Accessed via the viewset
|
||||
self.assertEqual(viewset.get_admin_base_path(), "deep/within/the/admin")
|
||||
# Accessed via the model
|
||||
|
@ -216,3 +247,13 @@ class TestAdminURLs(WagtailTestUtils, TestCase):
|
|||
# Ensure AdminURLFinder returns the correct URL
|
||||
url_finder = AdminURLFinder(self.user)
|
||||
self.assertEqual(url_finder.get_edit_url(snippet), expected_url)
|
||||
# Chooser base path
|
||||
self.assertEqual(
|
||||
viewset.get_chooser_admin_base_path(),
|
||||
"choose/wisely",
|
||||
)
|
||||
# Get specific chooser URL
|
||||
self.assertEqual(
|
||||
reverse(viewset.chooser_viewset.get_url_name("choose")),
|
||||
expected_choose_url,
|
||||
)
|
||||
|
|
|
@ -617,6 +617,14 @@ class SnippetViewSet(ViewSet):
|
|||
#: If left unset, ``snippets/{app_label}/{model_name}`` is used instead.
|
||||
base_url_path = None
|
||||
|
||||
#: The URL namespace to use for the chooser admin views.
|
||||
#: If left unset, ``wagtailsnippetchoosers_{app_label}_{model_name}`` is used instead.
|
||||
chooser_admin_url_namespace = None
|
||||
|
||||
#: The base URL path to use for the chooser admin views.
|
||||
#: If left unset, ``snippets/choose/{app_label}/{model_name}`` is used instead.
|
||||
chooser_base_url_path = None
|
||||
|
||||
#: The view class to use for the index view; must be a subclass of ``wagtail.snippet.views.snippets.IndexView``.
|
||||
index_view_class = IndexView
|
||||
|
||||
|
@ -988,9 +996,9 @@ class SnippetViewSet(ViewSet):
|
|||
@property
|
||||
def chooser_viewset(self):
|
||||
return self.chooser_viewset_class(
|
||||
f"wagtailsnippetchoosers_{self.app_label}_{self.model_name}",
|
||||
self.get_chooser_admin_url_namespace(),
|
||||
model=self.model,
|
||||
url_prefix=f"snippets/choose/{self.app_label}/{self.model_name}",
|
||||
url_prefix=self.get_chooser_admin_base_path(),
|
||||
icon=self.icon,
|
||||
)
|
||||
|
||||
|
@ -1009,6 +1017,21 @@ class SnippetViewSet(ViewSet):
|
|||
return self.base_url_path.strip().strip("/")
|
||||
return f"snippets/{self.app_label}/{self.model_name}"
|
||||
|
||||
def get_chooser_admin_url_namespace(self):
|
||||
"""Returns the URL namespace for the chooser admin URLs for this model."""
|
||||
if self.chooser_admin_url_namespace:
|
||||
return self.chooser_admin_url_namespace
|
||||
return f"wagtailsnippetchoosers_{self.app_label}_{self.model_name}"
|
||||
|
||||
def get_chooser_admin_base_path(self):
|
||||
"""
|
||||
Returns the base path for the chooser admin URLs for this model.
|
||||
The returned string must not begin or end with a slash.
|
||||
"""
|
||||
if self.chooser_base_url_path:
|
||||
return self.chooser_base_url_path.strip().strip("/")
|
||||
return f"snippets/choose/{self.app_label}/{self.model_name}"
|
||||
|
||||
@property
|
||||
def url_finder_class(self):
|
||||
return type(
|
||||
|
|
|
@ -28,7 +28,7 @@ class AdminSnippetChooser(BaseChooser):
|
|||
def get_chooser_modal_url(self):
|
||||
try:
|
||||
return reverse(
|
||||
f"wagtailsnippetchoosers_{self.model._meta.app_label}_{self.model._meta.model_name}:choose"
|
||||
self.model.snippet_viewset.chooser_viewset.get_url_name("choose")
|
||||
)
|
||||
except NoReverseMatch:
|
||||
# This most likely failed because the model is not registered as a snippet.
|
||||
|
|
|
@ -234,6 +234,8 @@ class FullFeaturedSnippetViewSet(SnippetViewSet):
|
|||
icon = "cog"
|
||||
admin_url_namespace = "some_namespace"
|
||||
base_url_path = "deep/within/the/admin"
|
||||
chooser_admin_url_namespace = "my_chooser_namespace"
|
||||
chooser_base_url_path = "choose/wisely"
|
||||
|
||||
|
||||
register_snippet(FullFeaturedSnippet, viewset=FullFeaturedSnippetViewSet)
|
||||
|
|
Ładowanie…
Reference in New Issue