Django Rest Framework 完整性错误捕获

Dea*_*ada 5 django rest python-3.x django-rest-framework

在 Django Rest Framework 中,我使用了序列化器、视图集和路由器方法。每当我在 django Rest 框架的 API 视图中发布故意错误时,它都会抛出完整性错误。有没有办法尝试捕获错误,例如如果数据中没有错误,则继续保存,但是如果有错误,则会抛出包含错误列表的 JSON 响应,例如:

[{'section':'This field can not be blank', 'first_name':'This field can not be blank', 'middle_name':'This field can not be blank', 'last_name':'This field can not be blank'}]
Run Code Online (Sandbox Code Playgroud)

模型.py

from django.db import models

# Create your models here.
# class AuditTable(models.Model):
#   date_created = models.DateTimeField(auto_now_add=True)
    # test_field = models.CharField(max_length=50, null=True, blank=True)

class Section(models.Model):
    name = models.CharField(max_length=50, default=None)

    def __str__(self):
        return self.name

class Student(models.Model):
    section = models.ForeignKey(Section, default=None)
    first_name = models.CharField(max_length=50, default=None)
    middle_name = models.CharField(max_length=50, default=None)
    last_name = models.CharField(max_length=50, default=None)

    def __str__(self):
        full_name = "%s %s %s" % (self.first_name, self.middle_name, self.last_name)
        return full_name
Run Code Online (Sandbox Code Playgroud)

序列化器.py

from rest_framework import serializers
from rest_framework.response import Response

from . models import *

class SectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Section
        fields = ('name', )

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ('section', 'first_name', 'middle_name', 'last_name' )
Run Code Online (Sandbox Code Playgroud)

视图集.py

from rest_framework import viewsets

from . serializers import *
from . models import *

class SectionViewSet(viewsets.ModelViewSet):
    queryset = Section.objects.all()
    serializer_class = SectionSerializer

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
Run Code Online (Sandbox Code Playgroud)

路由器.py

from rest_framework import routers

from . viewsets import *

# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'students', StudentViewSet)
router.register(r'sections', SectionViewSet)
Run Code Online (Sandbox Code Playgroud)

urls.py

from django.conf.urls import include, url

from . import views
from . routers import router

urlpatterns = [
    url(r'^$', views.index, name='testing_sample_index' ),
    url(r'^restful-form/$', views.web_service_form, name='testing_sample_web_service' ),

    url(r'^api/', include(router.urls)),
]
Run Code Online (Sandbox Code Playgroud)

rar*_*iru 7

根据这个答案,解决方案是:

视图集.py

from django.db import IntegrityError    # Import IntegrityError
from rest_framework import viewsets
from rest_framework.exceptions import APIException  #Import APIException
from . serializers import *
from . models import *

class SectionViewSet(viewsets.ModelViewSet):
    queryset = Section.objects.all()
    serializer_class = SectionSerializer

    def create(self, request, *args, **kwargs):
        try:
            return super().create(request, *args, **kwargs)
        except IntegrityError as exc:
            raise APIException(detail=exc)
Run Code Online (Sandbox Code Playgroud)


Lin*_*via 5

如果您有,IntegrityError那么您的模型与数据库不同步。

您应该设置唯一性约束以匹配您的数据库方案。

请注意,DRF 可以使用 UniqueValidator 针对唯一约束进行验证


Ale*_*zov 4

默认CreateMixin实现会对任何验证错误引发异常。所以你可以编写自己的自定义 mixin...

class VerboseCreateModelMixin(object):
    """
    Create a model instance and return either created object or the validation errors.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

...然后在您的ViewSet

class SectionViewSet(VerboseCreateModelMixin, viewsets.ModelViewSet):
    queryset = Section.objects.all()
    serializer_class = SectionSerializer
Run Code Online (Sandbox Code Playgroud)