我正在尝试创建一个序列化程序,以使用一个有效载荷创建多个产品。这是我的尝试:
# 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" } ]
如何获得此类回复?
答案 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
注意::我只是强调逻辑,我没有测试解决方案