有没有办法让Django Rest Framework在出现数据库异常时自动响应HTTP_400_STATUS
?
(IntegrityError
等)
例如:我有一个具有唯一用户名字段的模型,并且我尝试使用一个通用的rest_framework.ListCreateAPIView
。如果序列化程序验证失败,通常会自动抛出HTTP_400_STATUS
,但这实际上是有效的输入,只是在数据库中无效。我应该怎么做?
发布于 2015-10-31 18:34:07
您应该扩展ListCreateAPIView
并捕获IntegrityError
,然后通过返回bad_request
来处理它
from django.views.defaults import bad_request
from rest_framework.generics import ListCreateAPIView
class MyListCreateAPIView(ListCreateAPIView):
def create(self, request, *args, **kwargs):
try:
return super(ListCreateAPIView,self).create(request, *args, **kwargs)
except IntegrityError:
return bad_request(request)
有趣的是,您可以引发一个SuspiciousOperation
,而不是显式地返回bad_request:
except IntegrityError:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation
然后django将返回一个400 BAD REQUEST
。
发布于 2018-06-10 00:55:56
虽然覆盖通用视图是一个完全有效的解决方案,但我认为更好的解决方案是使用Django REST框架的选项to implement custom exception handling。您可以通过创建一个处理程序函数来实现这一点,该函数将API视图中引发的异常转换为响应对象。要做到这一点,您所要做的就是通过在设置中覆盖它来告诉Django REST Framework您的自定义处理程序所在的位置:
REST_FRAMEWORK = {'EXCEPTION_HANDLER':'my_project.my_app.utils.custom_exception_handler'}
在指定的文件(在本例中为my_project/my_app/utils.py
)中,您将执行类似以下操作:
from __future__ import unicode_literals
from django.db import IntegrityError
from rest_framework.views import Response, exception_handler
from rest_framework import status
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first to get the standard error response.
response = exception_handler(exc, context)
# if there is an IntegrityError and the error response hasn't already been generated
if isinstance(exc, IntegrityError) and not response:
response = Response(
{
'message': 'It seems there is a conflict between the data you are trying to save and your current '
'data. Please review your entries and try again.'
},
status=status.HTTP_400_BAD_REQUEST
)
return response
正如文档中所说,值得注意的是,“异常处理程序只对引发的异常生成的响应进行调用”。(即仅当您执行以下操作时:serializer.is_valid(raise_exception=True)
)。但是,这只在您自己调用serializer.is_valid()
时才重要,因为"the generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above."也是如此,我只想指出,如果您希望稍后在给定视图中指定自定义IntegrityError
消息,则可以始终覆盖通用视图,正如其他答案所示,自定义异常处理程序不会插入默认消息,因为response
将不再为None
。
发布于 2016-07-19 05:54:14
要使用适当的rest_framework
(使用rest框架样式响应)来完成此操作:
from django.db import IntegrityError
from rest_framework import status
from rest_framework.generics import ListCreateAPIView
from rest_framework.response import Response
class MyListCreateAPIView(ListCreateAPIView):
def create(self, request, *args, **kwargs):
try:
return super(ListCreateAPIView, self).create(request, *args, **kwargs)
except IntegrityError:
content = {'error': 'IntegrityError'}
return Response(content, status=status.HTTP_400_BAD_REQUEST)
https://stackoverflow.com/questions/33450390
复制相似问题