Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

404 when page number is too high

If this filter REST query results in no values it will return an HTTP 200 with empty results:

http://server/path/entities?field=value&page=1

This one will return an HTTP 404 instead

http://server/path/entities?field=value&page=2

Obviously, there is no second page of results. Can I configure django-rest to return an empty HTTP 200, rather than an HTTP 404 in this scenario?

The GUI allows the user to page forward, then change the filter criteria, which can request the second URL and trigger a HTTP 404 and a user error.

I can ask the GUI team to treat a 404 as an empty result set, but I would rather that this just return an empty HTTP 200 from the server.

like image 982
clay Avatar asked Mar 16 '23 12:03

clay


2 Answers

You can create a custom pagination class that intercept NotFound exception raise in paginate_queryset() and return empty list instead

something like this

def paginate_queryset(self, queryset, request, view=None):
    """Checking NotFound exception"""
    try:
        return super(EmptyPagination, self).paginate_queryset(queryset, request, view=view)
    except NotFound:  # intercept NotFound exception
        return list()

def get_paginated_response(self, data):
    """Avoid case when self does not have page properties for empty list"""
    if hasattr(self, 'page') and self.page is not None:
        return super(EmptyPagination, self).get_paginated_response(data)
    else:
        return Response(OrderedDict([
            ('count', None),
            ('next', None),
            ('previous', None),
            ('results', data)
        ]))

and in config file

just tell DRF to use this custom pagination class

'DEFAULT_PAGINATION_CLASS': 'apps.commons.serializers.EmptyPagination',
like image 99
SaintTail Avatar answered Mar 18 '23 00:03

SaintTail


This is not (easily) possible, because the 404 is triggered as the result of a NotFound exception being raised, which will break out from the pagination logic. You could special case the NotFound exception in a custom exception handler, but you will be guessing based on the detail string. This isn't the best idea, as the message can change if

  • The message is changed in the DRF core translations
  • Your application is using translated strings

Which means that your application will suddenly return back to raising a 404 at some point in the future.

You're better off just having your GUI team treat a 404 as an empty result, or have them reset the page number when the filtering changes.

like image 24
Kevin Brown-Silva Avatar answered Mar 18 '23 00:03

Kevin Brown-Silva