【问题标题】:How to ignore error instead of returning 400 Bad Request?- Django Rest Framework如何忽略错误而不是返回 400 Bad Request?- Django Rest Framework
【发布时间】:2018-12-22 05:58:47
【问题描述】:

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

当我发布创建新购物车时,它会运行一些验证以查找优惠券是否存在。如果不存在,则返回错误 400,表示该对象不存在。 我不想要 400 错误,我需要它来继续将优惠券返回为 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,
        }

views.py

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

【问题讨论】:

  • 你的模型是什么样的?
  • coupon = models.ForeignKey('carts.Coupon', related_name='carts', on_delete=models.SET_NULL, null=True, )

标签: python django rest api django-rest-framework


【解决方案1】:

根据Django REST Framework docs,你需要在你的序列化器的相关字段上设置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

【讨论】:

    【解决方案2】:

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

    这里有一个很好的post@关于模型上null和blank的区别

    【讨论】:

    • 我没有解决问题。当用户编写错误的优惠券代码时,我仍然会收到异常 Coupon.DoesNotExist。
    • 您确定在发布时为优惠券 ID 传递了 null 或空白。听起来好像有些东西在发布时作为 id 传递。如果传递 null 或空白,则没有理由抛出异常。如果所有其他方法都失败,则将整个事情包装在尝试中,并捕获 DNE 错误,只需使用 pass
    • 是的,我敢肯定,因为如果我不传递任何代码,它会按预期工作,设置 Coupon = Null。问题是输入错误代码时,异常对象不存在。
    • 代码错误是什么意思?好像输入了不正确的ID?也许您可以发布一个代码示例来说明您的意思
    • 是的,但是我使用的是 SlugRelatedField,所以它不是 ID,它是一个名为 code 的 Slug 字段。
    【解决方案3】:

    我解决了以下问题:

    从 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,
            }
    

    【讨论】:

      猜你喜欢
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多