2015-10-31 120 views
2

有没有什么办法让Django Rest Framework在出现数据库异常时自动回复HTTP_400_STATUSDjango Rest框架数据库错误异常处理

IntegrityError等)

例子:我有一个唯一的用户名域的模型,我试图用一个通用的rest_framework.ListCreateAPIView。如果序列化器验证失败,通常会自动抛出HTTP_400_STATUS,但这实际上是有效的输入,只是在数据库中无效。我应该在这里做什么?

+0

我回答了您的问题吗?如果是,请接受答案,如果没有,请说明缺少的内容。 –

回答

0

您应该扩展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

+0

这似乎是要走的路 - 但如果它只是接管创建的问题,重写perform_create方法并在那里捕获异常会更好吗?我想我最初的问题出现了,因为看起来很奇怪,我需要在每种情况下都包含这个catch,而我们可能会碰到一个独特的约束,而不是仅仅自动返回一个400. – arooo

+0

如果你喜欢它,甚至可以包装调度,使它成为一个混合 –

2

做到这一点使用rest_framework正确的(与休息的框架样式响应):

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

-1

我这是怎么解决这个问题的CreateView的

class MyModelCreate(CreateView): 

    model = MyModel 
    fields = '__all__' 
    success_url = reverse_lazy('MyModels') # In case of success the user will be redirect to the listview. This is defined on your urls.py 

    def form_valid(self, form):   
     try:   
      return super(MyModelCreate, self).form_valid(form) 
     except IntegrityError as e: 
      messages.error(self.request, 'Integrity error. The name already exists. ' + str(e)) # You don't need to use the str(e). It is just for you to know what is going on. 
      return HttpResponseRedirect(reverse('MyModel_create',)) 

在您模板,您只需添加以下几行

{% if messages %} 
<ul class="messages"> 
    {% for message in messages %} 
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> 
    {% endfor %} 
</ul> 
{% endif %} 

img