首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Django Rest框架数据库错误异常处理

Django Rest框架数据库错误异常处理
EN

Stack Overflow用户
提问于 2015-10-31 18:11:28
回答 4查看 9K关注 0票数 11

有没有办法让Django Rest Framework在出现数据库异常时自动响应HTTP_400_STATUS

(IntegrityError等)

例如:我有一个具有唯一用户名字段的模型,并且我尝试使用一个通用的rest_framework.ListCreateAPIView。如果序列化程序验证失败,通常会自动抛出HTTP_400_STATUS,但这实际上是有效的输入,只是在数据库中无效。我应该怎么做?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-10-31 18:34:07

您应该扩展ListCreateAPIView并捕获IntegrityError,然后通过返回bad_request来处理它

代码语言:javascript
复制
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:

代码语言:javascript
复制
        except IntegrityError:
            from django.core.exceptions import SuspiciousOperation
            raise SuspiciousOperation

然后django将返回一个400 BAD REQUEST

票数 6
EN

Stack Overflow用户

发布于 2018-06-10 00:55:56

虽然覆盖通用视图是一个完全有效的解决方案,但我认为更好的解决方案是使用Django REST框架的选项to implement custom exception handling。您可以通过创建一个处理程序函数来实现这一点,该函数将API视图中引发的异常转换为响应对象。要做到这一点,您所要做的就是通过在设置中覆盖它来告诉Django REST Framework您的自定义处理程序所在的位置:

代码语言:javascript
复制
REST_FRAMEWORK = {'EXCEPTION_HANDLER':'my_project.my_app.utils.custom_exception_handler'}

在指定的文件(在本例中为my_project/my_app/utils.py)中,您将执行类似以下操作:

代码语言:javascript
复制
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

票数 21
EN

Stack Overflow用户

发布于 2016-07-19 05:54:14

要使用适当的rest_framework (使用rest框架样式响应)来完成此操作:

代码语言:javascript
复制
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)

Here is a list of available HTTP 400 status codes

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33450390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档