如何忽略错误而不是返回400错误请求?-Django Rest框架



我有一个名为Cart的模型。购物车有优惠券的外键。

当我POST创建一个新的Cart时,它会运行一些验证来查找Coupon是否存在。如果不存在,则返回错误400,说明对象不存在。我不想要一个400错误,我需要它来继续返回Coupon为Null的过程。

serializers.py

class CartSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(format='hex', read_only=True)
delivery = DeliverySerializer(required=False, write_only=True)
customer = CustomerSerializer(required=False, write_only=True)
coupon = CouponSerializer(
required=False,
)
totals = serializers.SerializerMethodField()

class CouponSerializer(serializers.Serializer):
code = serializers.SlugRelatedField(
slug_field='code',
required=False,
source='coupon',
queryset=Coupon.objects.only_valid(),
)
def to_representation(self, coupon):
return {
'code': coupon.code,
'discount_amount': coupon.discount_amount,
'discount_percentage': coupon.discount_percentage,
'only_first_order': coupon.only_first_order,
}

视图.py

class CartViewset(CreateModelMixin, GenericViewSet):
queryset = Cart.objects.all()
serializer_class = CartSerializer
permission_classes = (AllowAny,)

您需要将blank=True添加到模型中,因为它是ForeignKey优惠券=models.ForeignKey('carts.Coupon',related_name='carts',on_delete=models.SET_NULL, null=True, blank=True )

这是一篇关于模型上零和空白的区别的好文章

根据Django REST Framework文档,您需要在序列化程序中的相关字段上设置allow_null=True

class CartSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(format='hex', read_only=True)
delivery = DeliverySerializer(required=False, write_only=True)
customer = CustomerSerializer(required=False, write_only=True)
coupon = CouponSerializer(
required=False,
allow_null=True,
)
totals = serializers.SerializerMethodField()

请注意,您的Cart模型中也需要null=True

我通过以下操作解决了问题:

重写SlugRelatedField中的to_internal_value方法,将DoesNotExist异常处理为不引发错误。

class CouponSlugRelatedField(serializers.SlugRelatedField):
def to_internal_value(self, code):
try:
return Coupon.objects.only_valid().get(code=code)
except Coupon.DoesNotExist:
return Coupon.objects.none()

class CouponSerializer(serializers.Serializer):
code = CouponSlugRelatedField(
slug_field='code',
required=False,
source='coupon',
allow_null=True,
queryset=Coupon.objects.only_valid()
)
def to_representation(self, coupon):
return {
'code': coupon.code,
'discount_amount': coupon.discount_amount,
'discount_percentage': coupon.discount_percentage,
'only_first_order': coupon.only_first_order,
}

最新更新