如何在创建之前验证Django REST框架中的输入?

2024-04-29 00:16:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个模型,用“选择你自己的价格”模型来表示一个购物项目。卖家可以选择让客户从低、中、高价格中选择。因此,我需要验证用户是否为每个购物项目发送了这三个值之间的有效选项

目前,我的模型如下所示:

class PurchaseItem(models.Model):
    """
    PurchaseItem.
    "price" should be treated as a suggestion. We allow users to choose their own price, so we need to validate that
    what comes here is a valid choice from the Listing. Otherwise, a malicious user might be able to charge whatever
    they want. The Listing model has a ListingPrice with a required 'suggested_cost' field and optional low, medium,
    high costs.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    item = models.ForeignKey(Listing, on_delete=models.DO_NOTHING)
    price = models.DecimalField(max_digits=8, decimal_places=2, blank=False, null=False)
    currency = models.CharField(max_length=30, choices=SUPPORTED_CURRENCIES, default='USD')
    created_date = models.DateTimeField(auto_now_add=True)
    purchased_by = models.ForeignKey(User, on_delete=models.CASCADE)

    def clean(self):
        listing_price = self.item.price
        valid_prices = [listing_price.suggested_cost]
        if listing_price.supports_cost_choice is True:
            valid_prices = valid_prices + [listing_price.low_cost, listing_price.medium_cost, listing_price.high_cost]
        if self.price not in valid_prices:
            raise ValidationError("Selected price is not a valid option.")
        super(PurchaseItem, self).clean()

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        self.clean() # <---- Workaround. I'm trying to remove this.
        super(PurchaseItem, self).save(force_insert, force_update, using, update_fields)

当直接保存到数据库中或通过Django管理面板进行交互时,Django将调用clean,我将进行验证,如果价格无效,则抛出错误,一切正常。效果很好

问题:
我的问题在创建视图集中。我调用POST端点,希望它在保存项目时抛出错误,但它会跳过清除阶段。我添加断点,它从不调用clean。因此,我添加了一个变通方法,在保存时手动调用clean

问题:
如何摆脱对self.clean()的手动调用?或者,如果价格无效,如何确保viewset抛出错误?目前,序列化程序的is_valid正在返回true,我不确定序列化程序是否有责任在提交时查找有效价格。为什么序列化程序创建无效对象而不是运行clean方法并抛出验证错误


Tags: toselfcleanfalseismodelsupdate价格
1条回答
网友
1楼 · 发布于 2024-04-29 00:16:43

在序列化程序文件中:

class NameOfYOurModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = PurchaseItem
        fields = (
            'price',
        )

    def validate_price(self, valor):  # noqa
        # Just an example! I do not know the name of the field and other things; but this will work as a validation to your data.
        if value > 0:
        # Here is another example: only you can add the condition!
            return valor
        raise serializers.ValidationError('Description of the error!')

相关问题 更多 >