在 Django Rest Framework 中找不到资源时返回自定义 404 错误

Posted

技术标签:

【中文标题】在 Django Rest Framework 中找不到资源时返回自定义 404 错误【英文标题】:Return Custom 404 Error when resource not found in Django Rest Framework 【发布时间】:2015-10-01 12:50:36 【问题描述】:

我正在学习Django Rest Framework,也是 django 的新手。当客户端将访问未找到的资源时,我想在 json 中返回自定义 404 错误。

我的urls.py 看起来像这样:

urlpatterns = [
    url(r'^mailer/$', views.Mailer.as_view(), name='send-email-to-admin')
]

其中我只有一个资源,可以通过URI访问,http://localhost:8000/mailer/

现在,当客户端访问像 http://localhost:8000/ 这样的任何其他 URI 时,API 应该返回像这样的 404-Not Found 错误:


    "status_code" : 404
    "error" : "The resource was not found"

如果合适,请使用正确的代码 sn-ps 提出一些答案。

【问题讨论】:

我正在使用 Django REST framework exceptions 中描述的 custom_exception_handler 方法来捕获将在 function_view 或 class_views 中引发的异常。 【参考方案1】:

Ernest Ten answer的更新:

您还应该包括 在 urls.py

from django.http import JsonResponse
...other urls...
handler404 = lambda request, exception=None: JsonResponse('error': '404: The resource was not found', status=404)  

【讨论】:

【参考方案2】:

@Ernest Ten 的回答是正确的。但是,如果您使用的应用程序同时处理浏览器页面加载和 API 作为调用,我想添加一些输入。

我为此自定义了custom404函数

def custom404(request, exception=None):
    requested_html = re.search(r'^text/html', request.META.get('HTTP_ACCEPT')) # this means requesting from browser to load html
    api = re.search(r'^/api', request.get_full_path()) # usually, API URLs tend to start with `/api`. Thus this extra check. You can remove this if you want.

    if requested_html and not api:
        return handler404(request, exception) # this will handle error in the default manner

    return JsonResponse(
        'detail': _('Requested API URL not found')
    , status=404, safe=False)

【讨论】:

【参考方案3】:

您正在寻找handler404

这是我的建议:

    创建一个在所有 URL 模式都不匹配时应调用的视图。 将handler404 = path.to.your.view 添加到您的根 URLconf。

这是如何完成的:

    project.views

    from django.http import JsonResponse
    
    
    def custom404(request, exception=None):
        return JsonResponse(
            'status_code': 404,
            'error': 'The resource was not found'
        )
    

    project.urls

    from project.views import custom404
    
    
    handler404 = custom404
    

阅读error handling了解更多详情。

Django REST framework exceptions 也可能有用。

【讨论】:

这个解决方案不起作用,我按照你的描述做了。我也设置了DEBUG=False。但是,它返回html页面,未找到请求的URL/在此服务器上找不到. @AkshayPratapSingh 好像我误解了你。编辑了我的答案,它现在应该可以工作了。 我正在使用这个方法来捕捉rest_framwork视图的错误,但是它没有捕捉到url route non-matched error,它返回404错误。 您还应该包括状态码 404:JsonResponse('detail': "The resource was not found", 'status_code': 404, status=404)【参考方案4】:

根据 django 文档: Django 按顺序遍历每个 URL 模式,并在与请求的 URL 匹配的第一个模式处停止。参考:https://docs.djangoproject.com/en/1.8/topics/http/urls/

所以你可以在你创建的 urlpatterns 中添加另一个 url,它应该匹配所有 url 模式并将它们发送到返回 404 代码的视图。

即:

urlpatterns = [
url(r'^mailer/$', views.Mailer.as_view(), name='send-email-to-admin'),
url(r'^.*/$',views.Error404.as_view(),name='error404')]

【讨论】:

我应该怎么做才能制作 Error404 类视图,以便它在调用每个 HTTP 方法时返回我自定义的 JsonResponse 有没有办法在类视图中编写一个方法来处理所有 HTTP 方法,而不是为每个 HTTP 方法编写单独的方法。 您的解决方案也有效,但我使用函数 @api_view 不是基于类的视图,因此 api 在调用每个 HTTP 方法时返回相同的 JsonResponse

以上是关于在 Django Rest Framework 中找不到资源时返回自定义 404 错误的主要内容,如果未能解决你的问题,请参考以下文章

django使用rest_framework

Django Rest Framework

Django rest framework 身份和权限验证

Django Rest Framework:非模型服务

django-rest-framework - 在可浏览的 API 中自动生成表单?

在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?