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

时间:2015-07-13 09:54:22

标签: python django rest django-rest-framework

我正在学习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/

现在,当客户端访问任何其他URI,例如 http://localhost:8000/ 时,API应该返回404-Not Found错误,如下所示:

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

如果合适,请使用正确的代码段建议一些答案。

3 个答案:

答案 0 :(得分:15)

您正在寻找handler404

这是我的建议:

  1. 如果没有任何网址格式匹配,请创建一个应该调用的视图。
  2. handler404 = path.to.your.view添加到您的根URLconf。
  3. 以下是它的完成方式:

    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
      
    3. 阅读error handling了解详情。

      Django REST framework exceptions也可能有用。

答案 1 :(得分:2)

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

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

即:

ldapsearch -b "base directoty path" -D "cn=manager,dc=mydomain,dc=com" -W "ldap pwd"

答案 2 :(得分:0)

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