如何为批量(JSON对象数组)POST请求中的每个实例返回错误消息?

时间:2019-03-25 13:02:42

标签: python django django-rest-framework

我正在研究餐厅订购应用程序。将创建商品订单,因为JSON对象数组将过帐到orderdetail模型,但是当任何商品的库存不足时,将引发Exception。但是我只能给出一个错误,而不是所有错误。

例如:

当前库存

苹果5个

芒果10个

当我订购苹果10个和芒果20个时。我想收到一条错误消息,提示“苹果和芒果库存不足”。但是目前,我只得到“苹果库存不足”的信息,因为我将苹果作为数组中的第一个对象。如果将芒果作为第一个对象,我将得到“芒果存量不足”。

有关全部代码,您可以检查回购链接:here。 我的模特:

class Menu(models.Model):
    image = models.ImageField(upload_to=path_and_rename)
    name = models.CharField(max_length=100)
    price = models.IntegerField()
    category = models.IntegerField()
    availability = models.BooleanField(default=False)
    qty = models.IntegerField(default=100)
    sellerID = models.ForeignKey(Seller, on_delete=models.PROTECT)


class OrderDetail(models.Model):
    orderID = models.ForeignKey(Order, on_delete=models.PROTECT)
    menuID = models.ForeignKey(Menu, on_delete=models.PROTECT)
    price = models.IntegerField()
    qty = models.IntegerField()
    tableNumber = models.IntegerField()
    done = models.BooleanField(default=False)
    # orderTime = models.DateTimeField(auto_now_add=True)
    # finishTime = models.DateTimeField(auto_now=True)
    finishTime = models.DateTimeField(null=True, blank=True)
    sellerID = models.ForeignKey(Seller, on_delete=models.PROTECT)

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if self.done:
            self.finishTime = datetime.datetime.now()
        else:
            menuID = self.menuID.id
            menuObject = Menu.objects.get(id=menuID)
            tempQty = menuObject.qty - self.qty
            if tempQty>=0:
                menuObject.qty = tempQty
                menuObject.save()
            else:
                # return serializers.ValidationError()
                raise serializers.ValidationError(menuObject.name + ": STOCK IS NOT SUFFICIENT")
        super().save(force_insert, force_update, using, update_fields)

我的观点:

class OrderDetailViewset(viewsets.ModelViewSet):
    serializer_class = serializers.OrderDetailSerializer
    def get_queryset(self):
        queryset = models.OrderDetail.objects.all()
        sellerID = self.request.query_params.get('sellerID', None)
        done = self.request.query_params.get('done', None)
        if sellerID is not None:
            queryset = queryset.filter(sellerID=sellerID)
            if done is not None:
                queryset = queryset.filter(sellerID=sellerID, done=done)
        return queryset

    # Enable Post of List
    # https://stackoverflow.com/questions/37329771/django-rest-bulk-post-post-array-of-json-objects
    # Accessed on March 9, 2019
    def create(self, request, pk=None, company_pk=None, project_pk=None):
        is_many = True if isinstance(request.data, list) else False

        serializer = self.get_serializer(data=request.data, many=is_many)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

我认为问题出在我引发异常的地方,但是我不知道如何解决它。谢谢你!

1 个答案:

答案 0 :(得分:1)

正如您正确地说的那样,问题出在您引发异常的位置:ModelViewSet.create> serializer.is_valid(raise_exception=True)

基于DRF docs

  

反序列化数据时,在尝试访问经过验证的数据或保存对象实例之前,始终需要调用is_valid()。

...

  

.is_valid()方法带有一个可选的raise_exception标志,如果存在验证错误,它将导致引发serializers.ValidationError异常。

     

这些异常由REST框架提供的默认异常处理程序自动处理,默认情况下将返回HTTP 400 Bad Request响应。

因此,到达此验证的第一个对象将返回您提到的HTTP 400 Bad Request

您需要自定义验证,以不返回HTTP 400 Bad Request,在serializer中实现您自己的验证,和/或在视图中捕获并处理这些异常,这样您就可以您处理这些大负载所需的灵活性。

看看DRF codeDRF docs

祝你好运!