【问题标题】:Django DRF how to limit items created at a time in serializerDjango DRF如何限制在序列化程序中一次创建的项目
【发布时间】:2019-05-07 17:08:40
【问题描述】:

我正在设置 POST API 端点(在 Django Rest Framework 中)以添加拍卖报价。但是有两个限制我不知道如何处理:

1) 投标人每次拍卖最多可以有三个报价

2) 同一投标人对同一拍卖的报价不能相同(重复)

投标人可以在一个请求中申请多个报价,但我不知道如何验证他发送的报价不超过 3 个,以及如何检查他之前发布 2 个报价时是否发送了 2 个新报价(所以他超出限制)。

同样适用于优惠重复,我尝试在序列化程序“验证”方法中检查已发送优惠,但在处理新优惠时没有发现任何内容。看起来他们是一起被提交到数据库的,不是吗?

Offer Viewset - 这里我使用 Stackoverflow 上的代码来允许在单个 POST 请求中创建项目列表

class OfferViewSet(viewsets.GenericViewSet, mixins.CreateModelMixin):

    serializer_class = OfferSerializer
    permission_classes = (IsValidBidder,)

    def get_serializer(self, *args, **kwargs):
        if isinstance(kwargs.get('data', {}), list):
            kwargs['many'] = True
        return super(OfferViewSet, self).get_serializer(*args, **kwargs)

这里是 OfferSerializer 的一部分

def validate(self, attrs):
    ...
    already_placed_offers_qs = Offer.objects.filter(
        bidder=attrs['bidder'],
        auction=attrs['auction']
    )

    if already_placed_offers_qs.count() >= 3:
        raise LimitExceededError()

    # check for already existing same object
    if already_placed_offers_qs.filter(...).exists():
        raise DuplicationError()

    return attrs

很遗憾,如果我在一个请求中提交多个报价,则此验证不起作用。

我希望它会检查单个投标人是否没有超过每次拍卖 3 个报价的限制,无论他是发送一个包含 4 个报价的单个请求,还是一个包含一个报价的多个请求。 它还应该检查重复项,例如如果在一个请求中发送多个优惠,它应该防止添加重复项(就像我在 validate 方法中尝试的那样)

提前致谢!

【问题讨论】:

    标签: python django rest django-rest-framework


    【解决方案1】:

    独一无二的在一起

    覆盖 (2) 相对简单,可以通过使必要的字段(userauctionprice,可能?)在 at at the model levelat the serializer level 一起唯一来完成。

    列表验证

    (1) 最好通过编写自己的list serializer 来处理并将验证放在那里。像这样的:

    class OfferListSerializer(serializers.ListSerializer):
        def validate(self, attrs):
            already_placed_offers_qs = Offer.objects.filter(
                bidder=attrs['bidder'],
                auction=attrs['auction']
            )
            if already_placed_offers_qs.count() + len(attrs) > 3:
                raise LimitExceededError()
    
            return attrs
    
        ...
    
    class OfferSerializer(serializers.Serializer):
        ...
        class Meta:
            list_serializer_class = OfferListSerializer
            ...
    

    注意:我使用了您的LimitExceededError,但在我自己的代码中,我通常使用serializers.ValidationError,除非我有理由想自己处理错误

    【讨论】:

    • 非常感谢@RishiG 对 ListSerializer 的解释,这正是我正在寻找的将要创建的限制实例。关于重复,您的想法肯定是惯用的,但恐怕在模型中指定的 unique_together 在 ListSerializers 中以某种方式没有得到尊重,它只是忽略了它。你知道为什么吗?
    • 这就是为什么我建议这两个选项(在序列化程序或模型中指定)。在模型中指定仅在您尝试保存到数据库时进行检查。不过,不确定指定您自己的ListSerializer 是否对unique_together 有任何影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-25
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多