mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-25 02:53:58 +03:00
fix: fallback on CursorPagination ordering if unset on the view (#8954)
* this commit fixes the usage of a CursorPagination combined with a view implementing an ordering filter, without a default ordering value. * former behavior was to fetch the ordering value from the filter, and raises an error if the value was None, preventing the fallback on the ordering set on the CursorPagination class itself. * we reversed the logic by getting first the value set on the class, and override it by the ordering filter if the parameter is present
This commit is contained in:
parent
54307a4394
commit
f1a11d41cb
|
@ -801,6 +801,10 @@ class CursorPagination(BasePagination):
|
|||
"""
|
||||
Return a tuple of strings, that may be used in an `order_by` method.
|
||||
"""
|
||||
# The default case is to check for an `ordering` attribute
|
||||
# on this pagination instance.
|
||||
ordering = self.ordering
|
||||
|
||||
ordering_filters = [
|
||||
filter_cls for filter_cls in getattr(view, 'filter_backends', [])
|
||||
if hasattr(filter_cls, 'get_ordering')
|
||||
|
@ -811,17 +815,10 @@ class CursorPagination(BasePagination):
|
|||
# then we defer to that filter to determine the ordering.
|
||||
filter_cls = ordering_filters[0]
|
||||
filter_instance = filter_cls()
|
||||
ordering = filter_instance.get_ordering(request, queryset, view)
|
||||
assert ordering is not None, (
|
||||
'Using cursor pagination, but filter class {filter_cls} '
|
||||
'returned a `None` ordering.'.format(
|
||||
filter_cls=filter_cls.__name__
|
||||
)
|
||||
)
|
||||
else:
|
||||
# The default case is to check for an `ordering` attribute
|
||||
# on this pagination instance.
|
||||
ordering = self.ordering
|
||||
ordering_from_filter = filter_instance.get_ordering(request, queryset, view)
|
||||
if ordering_from_filter:
|
||||
ordering = ordering_from_filter
|
||||
|
||||
assert ordering is not None, (
|
||||
'Using cursor pagination, but no ordering attribute was declared '
|
||||
'on the pagination class.'
|
||||
|
|
|
@ -632,6 +632,24 @@ class CursorPaginationTestsMixin:
|
|||
ordering = self.pagination.get_ordering(request, [], MockView())
|
||||
assert ordering == ('created',)
|
||||
|
||||
def test_use_with_ordering_filter_without_ordering_default_value(self):
|
||||
class MockView:
|
||||
filter_backends = (filters.OrderingFilter,)
|
||||
ordering_fields = ['username', 'created']
|
||||
|
||||
request = Request(factory.get('/'))
|
||||
ordering = self.pagination.get_ordering(request, [], MockView())
|
||||
# it gets the value of `ordering` provided by CursorPagination
|
||||
assert ordering == ('created',)
|
||||
|
||||
request = Request(factory.get('/', {'ordering': 'username'}))
|
||||
ordering = self.pagination.get_ordering(request, [], MockView())
|
||||
assert ordering == ('username',)
|
||||
|
||||
request = Request(factory.get('/', {'ordering': 'invalid'}))
|
||||
ordering = self.pagination.get_ordering(request, [], MockView())
|
||||
assert ordering == ('created',)
|
||||
|
||||
def test_cursor_pagination(self):
|
||||
(previous, current, next, previous_url, next_url) = self.get_pages('/')
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user