404 当页码太高时

404 when page number is too high

如果此过滤器 REST 查询没有结果,它将 return 一个 HTTP 200,结果为空:

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

这个将 return 改为 HTTP 404

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

很明显,没有第二页的结果。在这种情况下,我可以将 django-rest 配置为 return 空 HTTP 200 而不是 HTTP 404 吗?

GUI 允许用户向前翻页,然后更改过滤条件,这可以请求第二个 URL 并触发 HTTP 404 和用户错误。

我可以要求 GUI 团队将 404 视为空结果集,但我宁愿这只是 return 来自服务器的空 HTTP 200。

这不太可能(很容易),因为 404 作为结果触发 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,但您将根据详细字符串进行猜测。这不是最好的主意,因为如果

,消息可能会改变
  • DRF 核心翻译中的消息已更改
  • 您的应用程序正在使用翻译后的字符串

这意味着您的应用程序会在将来的某个时候突然 return 重新引发 404。

您最好让您的 GUI 团队将 404 视为空结果,或者让他们在过滤更改时重置页码

您可以创建一个自定义分页 class 来拦截 NotFoundpaginate_queryset() 和 return 空列表中引发的异常

像这样

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)
        ]))

并在配置文件中

只需告诉 DRF 使用此自定义分页 class

'DEFAULT_PAGINATION_CLASS': 'apps.commons.serializers.EmptyPagination',