Allow ChooserViewSet to be filtered by specified URL parameters

pull/10863/head
Matt Westcott 2023-09-05 00:46:16 +01:00
rodzic 8a52269da5
commit 7b64f08e74
5 zmienionych plików z 34 dodań i 1 usunięć

Wyświetl plik

@ -128,6 +128,7 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
.. autoattribute:: edit_item_text
.. autoattribute:: per_page
.. autoattribute:: preserve_url_parameters
.. autoattribute:: url_filter_parameters
.. autoattribute:: choose_view_class
.. autoattribute:: choose_results_view_class
.. autoattribute:: chosen_view_class

Wyświetl plik

@ -12,7 +12,9 @@ class TestChooserViewSetWithFilteredObjects(WagtailTestUtils, TestCase):
Advert.objects.create(text="Head On, apply directly to the forehead")
advert2 = Advert.objects.create(text="We like the subs")
advert2 = Advert.objects.create(
url="https://quiznos.com", text="We like the subs"
)
advert2.tags.add("animated")
def test_get(self):
@ -20,3 +22,16 @@ class TestChooserViewSetWithFilteredObjects(WagtailTestUtils, TestCase):
response_html = json.loads(response.content)["html"]
self.assertIn("We like the subs", response_html)
self.assertNotIn("Head On, apply directly to the forehead", response_html)
def test_filter_by_url(self):
response = self.client.get(
"/admin/animated_advert_chooser/", {"url": "https://quiznos.com"}
)
response_html = json.loads(response.content)["html"]
self.assertIn("We like the subs", response_html)
response = self.client.get(
"/admin/animated_advert_chooser/", {"url": "https://subway.com"}
)
response_html = json.loads(response.content)["html"]
self.assertNotIn("We like the subs", response_html)

Wyświetl plik

@ -130,6 +130,7 @@ class BaseChooseView(
template_name = "wagtailadmin/generic/chooser/chooser.html"
results_template_name = "wagtailadmin/generic/chooser/results.html"
construct_queryset_hook_name = None
url_filter_parameters = []
def get_object_list(self):
return self.model_class.objects.all()
@ -174,6 +175,15 @@ class BaseChooseView(
return FilterForm(self.request.GET)
def filter_object_list(self, objects):
filters = {}
for filter in self.url_filter_parameters:
try:
filters[filter] = self.request.GET[filter]
except KeyError:
pass
if filters:
objects = objects.filter(**filters)
if self.construct_queryset_hook_name:
# allow hooks to modify the queryset
for hook in hooks.get_hooks(self.construct_queryset_hook_name):

Wyświetl plik

@ -35,6 +35,10 @@ class ChooserViewSet(ViewSet):
#: form submissions within the chooser modal workflow.
preserve_url_parameters = ["multiple"]
#: A list of URL query parameters that, if present in the url, should be applied as filters to the queryset.
#: (These should also be listed in `preserve_url_parameters`.)
url_filter_parameters = []
#: The view class to use for the overall chooser modal; must be a subclass of ``wagtail.admin.views.generic.chooser.ChooseView``.
choose_view_class = chooser_views.ChooseView
@ -93,6 +97,7 @@ class ChooserViewSet(ViewSet):
"model": self.model,
"permission_policy": self.permission_policy,
"preserve_url_parameters": self.preserve_url_parameters,
"url_filter_parameters": self.url_filter_parameters,
"create_action_label": self.create_action_label,
"create_action_clicked_label": self.create_action_clicked_label,
"creation_form_class": self.creation_form_class,

Wyświetl plik

@ -255,6 +255,8 @@ class ToyViewSetGroup(ModelViewSetGroup):
class AnimatedAdvertChooserViewSet(ChooserViewSet):
model = Advert
register_widget = False # don't make this the registered widget for Advert
url_filter_parameters = ["url"]
preserve_url_parameters = ["multiple", "url"]
def get_object_list(self):
return Advert.objects.filter(tags__name="animated")