【问题标题】:Return Custom 404 Error when resource not found in Django Rest Framework在 Django Rest Framework 中找不到资源时返回自定义 404 错误
【发布时间】: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 中引发的异常。

标签: python django rest django-rest-framework


【解决方案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

      这是我的建议:

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

      这是如何完成的:

      1. project.views

        from django.http import JsonResponse
        
        
        def custom404(request, exception=None):
            return JsonResponse({
                'status_code': 404,
                'error': 'The resource was not found'
            })
        
      2. 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
      猜你喜欢
      • 2017-06-21
      • 2015-04-27
      • 2016-03-21
      • 1970-01-01
      • 2018-07-31
      • 2021-02-28
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      相关资源
      最近更新 更多