在 Django REST 中引发异常
Posted
技术标签:
【中文标题】在 Django REST 中引发异常【英文标题】:Raising Exceptions in Django REST 【发布时间】:2015-10-24 07:18:35 【问题描述】:我正在尝试在 django rest 框架中测试异常。 基于http://www.django-rest-framework.org/api-guide/exceptions/raise NotFound,
默认情况下,此异常会导致带有 HTTP 状态的响应 代码“404 未找到”。
但是,当我发出 GET(到 /example1)时,我得到一个 500 ,
Request Method: GET
Request URL: http://192.168.59.103:8002/example1
Django Version: 1.8.3
Exception Type: NotFound
Exception Value:
not found
Exception Location: /home/djangoapp/testtools/api/views.py in example1, line 7
Python Executable: /usr/bin/python
详情如下,
settings.py
REST_FRAMEWORK = 'EXCEPTION_HANDLER':'rest_framework.views.exception_handler'
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
)
urls.py
from django.conf.urls import include, url
from api import views
urlpatterns = [
url(r'example1', views.example1),
]
views.py
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.exceptions import APIException,ParseError,NotFound
def example1(request):
raise NotFound("not found")
有什么想法吗?
【问题讨论】:
在您对@ArpitGoyal 的回答中,您说您实际上想知道如何为任何 URL 生成您自己的 404 响应,而不仅仅是此示例代码。如果这是真的,你能澄清一下这个问题吗? 【参考方案1】:from rest_framework.exceptions import NotFound
NotFound
类是从APIException
扩展而来的。 APIException
的默认状态码是500 Internal Server Error
,而NotFound
的默认状态码是404
。
因此,根据我的说法,您正试图在纯 django 视图中抛出 rest framework
异常。我在这里写了一个测试用例来检查引发错误的几率是多少。猜猜一个试图引发rest framework
异常的简单django 视图不会被视为视图错误。但是在提供装饰器并将其声明为 API 视图时,它会进入 exception_handler
所以当你这样做时:
from rest_framework.decorators import api_view
@api_view()
def example1(request):
raise NotFound('not found')
这现在被识别为由 API 引发的异常,该异常进入您提供的默认 rest_framework
EXCEPTION_HANDLER
,并返回任何给定异常的响应。
它的docstring
说:
返回应该用于任何给定异常的响应。经过 默认我们处理 REST 框架
APIException
,还有 Django 的 内置ValidationError
、Http404
和PermissionDenied
例外。任何未处理的异常都可能返回None
,这将 导致引发 500 错误。
【讨论】:
好酷。说得通。此外,如果我随后抛出对 /example2 的请求,这是否应该不会引发 DRF 的 NotFound 而无需我配置任何其他内容。 如果代码保持不变,每个 url 的行为应该相同。 好的,我一定是遗漏了一些东西,因为它无法自动生成 404 JSON 响应 任何想法。你的答案回答了 90% 的问题,这只是最后一点。 我没听懂你。我唯一能想到的就是这样。 NotFound 是一个 api 异常,您只能在 APIView 上将其作为错误引发。在纯 django 视图中,它被识别为内部服务器错误。最后一部分是什么意思?【参考方案2】:我不确定你为什么要这样做。这是 DRF 在找不到资源时使用的内部异常。但是您在任何 DRF 机器之外的标准 Django 视图中使用它。如果你想这样做,你应该使用标准的 Django 异常:
from django.core.exceptions import Http404
def example1(request):
raise Http404('not found')
【讨论】:
【参考方案3】:尝试使用匹配所有可能 url 的正则表达式更改您的 url,并将其放在主 urls.py 的末尾
例如:
urlpatterns = [
url(r'^(?P<slug>[\w-]+)/', views.example1),
]
【讨论】:
以上是关于在 Django REST 中引发异常的主要内容,如果未能解决你的问题,请参考以下文章
可以在 Django transaction.atomic() 中捕获并重新引发异常吗?
Django REST Framework:当 POST 上存在额外字段时引发错误