Browse Source

Allow ordering from IndexView to work but still be overridden by ordering set in ModelViewSet (#11367)

Fixes #11165
Cynthia Kiser 1 năm trước cách đây
mục cha
commit
e4c80fd2c3

+ 1 - 0
CHANGELOG.txt

@@ -83,6 +83,7 @@ Changelog
  * Fix: Raise a 404 for bulk actions for models which don't exist instead of throwing a 500 error (Alex Tomkins)
  * Fix: Raise a `SiteSetting.DoesNotExist` error when retrieving settings for an unrecognised site (Nick Smith)
  * Fix: Ensure that defaulted or unique values declared in `exclude_fields_in_copy` are correctly excluded in new copies, resolving to the default value (Elhussein Almasri)
+ * Fix: Ensure that `default_ordering` set on IndexView is preserved if ModelViewSet does not specify an explicit ordering (Cynthia Kiser)
  * Docs: Document, for contributors, the use of translate string literals passed as arguments to tags and filters using `_()` within templates (Chiemezuo Akujobi)
  * Docs: Document all features for the Documents app in one location (Neeraj Yetheendran)
  * Docs: Add section to testing docs about creating pages and working with page content (Mariana Bedran Lesche)

+ 1 - 1
docs/extending/generic_views.md

@@ -78,7 +78,7 @@ You can group multiple `ModelViewSet`s' menu items inside a single top-level men
 
 ### Listing view
 
-The {attr}`~ModelViewSet.list_display` attribute can be set to specify the columns shown on the listing view. To customise the number of items to be displayed per page, you can set the {attr}`~ModelViewSet.list_per_page` attribute. Additionally, the {attr}`~ModelViewSet.ordering` attribute can be used to specify the default ordering of the listing view.
+The {attr}`~ModelViewSet.list_display` attribute can be set to specify the columns shown on the listing view. To customise the number of items to be displayed per page, you can set the {attr}`~ModelViewSet.list_per_page` attribute. Additionally, the {attr}`~ModelViewSet.ordering` attribute can be used to override the `default_ordering` configured in the listing view.
 
 You can add the ability to filter the listing view by defining a {attr}`~ModelViewSet.list_filter` attribute and specifying the list of fields to filter. Wagtail uses the django-filter package under the hood, and this attribute will be passed as django-filter's `FilterSet.Meta.fields` attribute. This means you can also pass a dictionary that maps the field name to a list of lookups.
 

+ 1 - 0
docs/releases/6.0.md

@@ -121,6 +121,7 @@ This feature was implemented by Nick Lee, Thibaud Colas, and Sage Abdullah.
  * Raise a 404 for bulk actions for models which don't exist instead of throwing a 500 error (Alex Tomkins)
  * Raise a `SiteSetting.DoesNotExist` error when retrieving settings for an unrecognised site (Nick Smith)
  * Ensure that defaulted or unique values declared in `exclude_fields_in_copy` are correctly excluded in new copies, resolving to the default value (Elhussein Almasri)
+ * Ensure that `default_ordering` set on IndexView is preserved if ModelViewSet does not specify an explicit ordering (Cynthia Kiser)
 
 
 ### Documentation

+ 29 - 2
wagtail/admin/tests/viewsets/test_model_viewset.py

@@ -715,9 +715,22 @@ class TestOrdering(WagtailTestUtils, TestCase):
             ],
         )
 
-    def test_custom_order(self):
+    def test_custom_order_from_query_args(self):
+        response = self.client.get(reverse("fctoy-alt3:index") + "?ordering=-name")
+        self.assertFalse(FeatureCompleteToy._meta.ordering)
+        self.assertEqual(
+            [obj.name for obj in response.context["object_list"]],
+            [
+                "DDDDDDDDDD",
+                "CCCCCCCCCC",
+                "BBBBBBBBBB",
+                "AAAAAAAAAA",
+            ],
+        )
+
+    def test_custom_order_from_view(self):
         response = self.client.get(reverse("feature_complete_toy:index"))
-        # Should respect the viewset's ordering
+        # Should respect the view's ordering
         self.assertFalse(FeatureCompleteToy._meta.ordering)
         self.assertEqual(
             [obj.name for obj in response.context["object_list"]],
@@ -729,6 +742,20 @@ class TestOrdering(WagtailTestUtils, TestCase):
             ],
         )
 
+    def test_custom_order_from_from_viewset(self):
+        response = self.client.get(reverse("fctoy-alt3:index"))
+        # The view has an ordering but it is overwritten by the viewset
+        self.assertFalse(FeatureCompleteToy._meta.ordering)
+        self.assertEqual(
+            [obj.name for obj in response.context["object_list"]],
+            [
+                "CCCCCCCCCC",
+                "AAAAAAAAAA",
+                "DDDDDDDDDD",
+                "BBBBBBBBBB",
+            ],
+        )
+
 
 class TestBreadcrumbs(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
     def setUp(self):

+ 4 - 2
wagtail/admin/viewsets/model.py

@@ -134,7 +134,7 @@ class ModelViewSet(ViewSet):
         return view_kwargs
 
     def get_index_view_kwargs(self, **kwargs):
-        return {
+        view_kwargs = {
             "template_name": self.index_template_name,
             "results_template_name": self.index_results_template_name,
             "list_display": self.list_display,
@@ -146,9 +146,11 @@ class ModelViewSet(ViewSet):
             "search_fields": self.search_fields,
             "search_backend_name": self.search_backend_name,
             "paginate_by": self.list_per_page,
-            "default_ordering": self.ordering,
             **kwargs,
         }
+        if self.ordering:
+            view_kwargs["default_ordering"] = self.ordering
+        return view_kwargs
 
     def get_add_view_kwargs(self, **kwargs):
         return {

+ 15 - 1
wagtail/test/testapp/views.py

@@ -201,6 +201,11 @@ class SearchTestModelViewSet(ModelViewSet):
     form_fields = ["title", "body"]
 
 
+class FeatureCompleteToyIndexView(IndexView):
+    model = FeatureCompleteToy
+    default_ordering = ["name", "-release_date"]
+
+
 class FeatureCompleteToyViewSet(ModelViewSet):
     model = FeatureCompleteToy
     url_namespace = "feature_complete_toy"
@@ -209,13 +214,13 @@ class FeatureCompleteToyViewSet(ModelViewSet):
     icon = "media"
     template_prefix = "customprefix/"
     index_template_name = "tests/fctoy_index.html"
+    index_view_class = FeatureCompleteToyIndexView
     list_display = ["name", BooleanColumn("is_cool"), UpdatedAtColumn()]
     list_filter = ["name", "release_date"]
     list_export = ["name", "release_date", "is_cool"]
     export_filename = "feature-complete-toys"
     export_headings = {"release_date": "Launch date"}
     list_per_page = 5
-    ordering = ["name", "-release_date"]
     # search_fields derived from the model
     inspect_view_enabled = True
     inspect_view_fields = ["strid", "release_date"]
@@ -262,6 +267,15 @@ class ToyViewSetGroup(ModelViewSetGroup):
             search_fields=["name"],
             search_backend_name=None,
         ),
+        ModelViewSet(
+            name="fctoy-alt3",
+            menu_label="FC Toys Alt 3",
+            model=FeatureCompleteToy,
+            exclude_form_fields=(),
+            index_view_class=FeatureCompleteToyIndexView,
+            list_display=["name", "strid", "release_date"],
+            ordering=["strid"],
+        ),
     )