简体   繁体   English

如何验证 django rest 框架的唯一约束?

[英]How to validate unique constraint on django rest framework?

How can i validate an unique constraint with a key that is not on the request payload?如何使用不在请求有效负载上的键验证唯一约束?

The key that i need to validate are user_id and sku but the request does not contain the user_id key.我需要验证的密钥是user_idsku ,但请求不包含user_id密钥。

Example of payload:有效载荷示例:

{'sku': '123', data: []}

The serializers:序列化器:

class ProductConfiguration(serializers.Serializer):

    min_quantity = serializers.IntegerField(required=True)
    price = serializers.DecimalField(
        required=True,
        decimal_places=2,
        max_digits=10,
        coerce_to_string=False
    )


class ProductSerializer(serializers.ModelSerializer):

    sku = serializers.CharField(required=True)
    data = ProductConfiguration(many=True, required=True)

    class Meta:
        model = WholeSale

        # the "id" and "user_id" columns should not be included on the response
        exclude = ['id', 'user']

I need to validate that the user and sku key already exist.我需要验证usersku密钥是否已经存在。

By default if the two keys user_id and sku were on the payload drf could take care of Unique error, how can i validate this two keys if one of them are not on the payload?默认情况下,如果两个键user_idsku在有效负载上drf可以处理Unique错误,如果其中一个不在有效负载上,我如何验证这两个键?

you can get user data from request您可以从请求中获取用户数据

request.user请求用户

Maybe pass it in to serializer from view也许将它从视图传递给序列化程序

data = request.data
data['user_id'] = request.user.pk
serializer = ProductSerializer(data)

in serializer you could do在序列化器中你可以做

def validate(self, data):
    user = data.get('user_id')
    sku = data.get('sku')

    record = WholeSale.objects.filter(user=user, sku=sku).first()

    if not record:
        raise serializers.ValidationError("This combo doesn't exist")

    return super().validate(data)
class ProductSerializer(serializers.ModelSerializer):
    def validate(self, attrs):
        if not Sku.objects.get(sku=attrs['sku']).exists() or not User.objects.get(id=attrs['id']).exists():
            raise serializers.ValidationError("Something doesn't exist")
        
        return attrs

    sku = serializers.CharField(required=True)
    data = ProductConfiguration(many=True, required=True)

    class Meta:
        model = WholeSale
        exclude = ['id', 'user']

Assuming that you have this model structure ( i am only taking the sku and user field).假设你有这个 model 结构(我只取skuuser字段)。 To achieve what you trying to do, in class meta provide a unique together constraints,为了实现你想要做的,在 class 元中提供了一个独特的约束,

class WholeSale(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sku = models.CharField(max_lenght=100)

    class Meta:
        unique_together = ['user', 'sku']

OR ,

simply overwrite the validate_unique method to achieve validation on both user and sku fields together.只需覆盖validate_unique方法即可同时对usersku字段进行验证。

class WholeSale(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sku = models.CharField(max_lenght=100)

    def validate_unique(self, *args, **kwargs):
        # super(WholeSale, self).validate_unique(*args, **kwargs) # python2
        super().validate_unique(*args, **kwargs) # python3
        if self.__class__.objects.filter(user=self.user, sku=self.sku).\
            exists():
            raise ValidationError(
                message='This (user, sku) already exists.',
            )

No need to validate explicitly from serializer无需从序列化程序显式验证

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM