Django DRF如何限制在序列化程序中一次创建的项目

时间:2019-05-07 17:08:40

标签: python django rest django-rest-framework

我正在设置POST API端点(在Django Rest Framework中)以添加要约拍卖。但是,我不确定如何处理两个约束:

1)竞标者每次竞价最多可以有三个出价

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

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

这同样适用于商品复制,我尝试在序列化程序中通过“验证”方法检查已发送的商品,但是在处理新商品时却找不到任何东西。看来他们是一起提交给数据库的,不是吗?

提供视图集-在这里,我使用了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方法中尝试过的一样)

谢谢!

1 个答案:

答案 0 :(得分:0)

独特在一起

覆盖(2)相对简单,可以通过使必填字段(userauctionprice,可能是唯一的){{3} }或at at the model level

列表验证

(1)最好是通过编写自己的at the serializer level并将验证放在其中来最好地处理。像这样:

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,除非我有理由要自己处理错误 >