在 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 错误的主要内容,如果未能解决你的问题,请参考以下文章