【问题标题】:Raising Exceptions in Django REST在 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 响应,而不仅仅是此示例代码。如果这是真的,你能澄清一下这个问题吗?

标签: django


【解决方案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 的 内置ValidationErrorHttp404PermissionDenied 例外。任何未处理的异常都可能返回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),
    ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-27
      • 2015-08-12
      • 1970-01-01
      • 2014-10-14
      • 2020-06-20
      • 1970-01-01
      • 2017-09-07
      • 2017-11-19
      相关资源
      最近更新 更多