Django Rest Framework:创建多个记录时如何在列表中出现错误

时间:2018-07-16 10:06:48

标签: django django-rest-framework

我正在尝试创建一个序列化程序,以使用一个有效载荷创建多个产品。这是我的尝试:

# models.py
class Product(models.Model):
    sku = models.CharField(unique=True)
    product_name = models.CharField()

# serializers.py
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

    def create(self, validated_data):
        try:
            product = create_product( **validated_data)
        except:
            raise CustomException( detail = { "error" : "Unable to create product" } )

# views.py
class ProductCreate(generics.CreateAPIView):

    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def get_serializer(self, *args, **kwargs):
        kwargs["many"] = True
        return super().get_serializer(*args, **kwargs)

因此,当数据干净时,此方法效果很好。这是回应:

[ { "id" : 1, "sku" : "12345", "product_name" : "Product A" },
  { "id" : 2, "sku" : "56789", "product_name" : "Product B" }]

但是,如果其中一种产品创建失败,则错误消息很简单:

# response
{ "error" : "Unable to create product" }

我想要的是一个响应列表,其中每个元素对应于请求中的product元素。例如,创建了产品A,但是产品B返回了错误。

[ { "id" : 1, "sku" : "12345", "product_name" : "Product A" },
  { "error" : "Unable to create product" } ]

如何获得此类回复?

3 个答案:

答案 0 :(得分:1)

您需要两个序列化器类。一个仅用于产品,另一个用于产品列表。

class ProductSerializer(ModelSerializer)
    class meta:
        model = Product


class ProductListSerializer(Serializer):
    productList = ProductSerializer(many=True)

您必须在每个序列化程序中覆盖create方法

答案 1 :(得分:1)

还取决于您是否要让序列化程序验证数据。

因为,如果您的一条记录未通过验证,则序列化程序将失败。

如果要添加通过验证但报告失败的记录,可以在视图的创建函数中执行以下操作:

class ProductCreate(generics.CreateAPIView):

    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def create(self, request, *args, **kwargs):

        response = []

        for product in self.request.data:
            serializer = self.get_serializer(data=product)

            if serializer.is_valid(raise_exception=False):
                self.perform_create(serializer)
                response.append(serializer.data)
            else:
                response.append({"error" : "your error message"})

        return Response(response, status=201)

注意:在这种情况下,创建序列化程序时不能设置“ many = True”。

现在的问题是,当对象写入数据库时​​是否还要捕获错误。在这种情况下,您需要在create-product所在的序列化器中执行此操作。但是,如果将对象保存到db失败,那么您可能会遇到更严重的问题,所以我个人会失败并返回错误。

答案 2 :(得分:0)

尝试这样的事情,

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

    def create(self, validated_data):
        errors = []
        try:
            product = create_product(**validated_data)
        except:
            errors.append({"error": validated_data})
        if errors:  # If atleast one error occured
            raise CustomException(detail=errors)
        # return your default case



注意::我只是强调逻辑,我没有测试解决方案