有没有什么办法让Django Rest Framework在出现数据库异常时自动回复HTTP_400_STATUS
?Django Rest框架数据库错误异常处理
(IntegrityError
等)
例子:我有一个唯一的用户名域的模型,我试图用一个通用的rest_framework.ListCreateAPIView
。如果序列化器验证失败,通常会自动抛出HTTP_400_STATUS
,但这实际上是有效的输入,只是在数据库中无效。我应该在这里做什么?
有没有什么办法让Django Rest Framework在出现数据库异常时自动回复HTTP_400_STATUS
?Django Rest框架数据库错误异常处理
(IntegrityError
等)
例子:我有一个唯一的用户名域的模型,我试图用一个通用的rest_framework.ListCreateAPIView
。如果序列化器验证失败,通常会自动抛出HTTP_400_STATUS
,但这实际上是有效的输入,只是在数据库中无效。我应该在这里做什么?
您应该扩展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
。
这似乎是要走的路 - 但如果它只是接管创建的问题,重写perform_create方法并在那里捕获异常会更好吗?我想我最初的问题出现了,因为看起来很奇怪,我需要在每种情况下都包含这个catch,而我们可能会碰到一个独特的约束,而不是仅仅自动返回一个400. – arooo
如果你喜欢它,甚至可以包装调度,使它成为一个混合 –
做到这一点使用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)
我这是怎么解决这个问题的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 %}
我回答了您的问题吗?如果是,请接受答案,如果没有,请说明缺少的内容。 –