diff --git a/bread/bread.py b/bread/bread.py index c36142e..f7311f6 100644 --- a/bread/bread.py +++ b/bread/bread.py @@ -265,8 +265,9 @@ def get_queryset(self): (prefix, self.get_sort_field_name_for_column(column_number))) # Add any ordering from the model's Meta data that isn't already included. # That will make the rest of the sort stable, if the model has some default sort order. + default_ordering = getattr(self, 'default_ordering', qset.model._meta.ordering) order_by_without_leading_dashes = [x.lstrip('-') for x in order_by] - for order_spec in qset.model._meta.ordering: + for order_spec in default_ordering: if order_spec.lstrip('-') not in order_by_without_leading_dashes: order_by.append(order_spec) qset = qset.order_by(*order_by) diff --git a/docs/changes.rst b/docs/changes.rst index cad777e..41ce749 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -3,6 +3,12 @@ Change Log ========== +0.5.1 - Dec 1, 2017 +------------------- + +* Allow specifying default ordering on views for cases when we + don't control the model and can't change the ordering there. + 0.5.0 - Nov 30, 2017 -------------------- diff --git a/docs/configuration.rst b/docs/configuration.rst index 3557ef9..05c8c6d 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -194,6 +194,10 @@ sorting (Otherwise, every time we show a new page, we could be working off a different sorting of the results!) If nothing else, include a sort on the primary key. + If you do not have control of the model and so cannot change its ordering there, + you can add a ``default_ordering`` attribute to the browse view. Bread will use that + if present, instead of the model's ordering. + Configuring the browse view: If the second item in the ``columns`` entry for a column is not a valid specification diff --git a/tests/test_browse.py b/tests/test_browse.py index 5d77bea..ce9dad6 100644 --- a/tests/test_browse.py +++ b/tests/test_browse.py @@ -80,6 +80,36 @@ def test_sort_all_ascending(self, mock_logger): # No exceptions logged self.assertFalse(mock_logger.exception.called) + @patch('bread.templatetags.bread_tags.logger') + def test_sort_most_ascending_with_override_default_order(self, mock_logger): + self.set_urls(self.bread) + self.bread.browse_view.default_ordering = ['-other__text', 'age'] + BreadTestModelFactory(name='999', other__text='012', age=50) + BreadTestModelFactory(name='555', other__text='333', age=60) + BreadTestModelFactory(name='111', other__text='555', age=10) + BreadTestModelFactory(name='111', other__text='555', age=20) + BreadTestModelFactory(name='111', other__text='555', age=5) + self.give_permission('browse') + url = reverse(self.bread.get_url_name('browse')) + '?o=0,1' + request = self.request_factory.get(url) + request.user = self.user + rsp = self.bread.get_browse_view()(request) + self.assertEqual(OK, rsp.status_code) + rsp.render() + results = rsp.context_data['object_list'] + + i = 0 + while i < len(results) - 1: + sortA = (results[i].name, results[i].other.text) + sortB = (results[i+1].name, results[i+1].other.text) + self.assertLessEqual(sortA, sortB) + if sortA == sortB: + # default sort is 'age' + self.assertLessEqual(results[i].age, results[i+1].age) + i += 1 + # No exceptions logged + self.assertFalse(mock_logger.exception.called) + @patch('bread.templatetags.bread_tags.logger') def test_sort_all_descending(self, mock_logger): self.set_urls(self.bread)