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

Python 如何验证django rest框架上的唯一约束?,python,django,django-rest-framework,Python,Django,Django Rest Framework,如何使用不在请求负载上的密钥验证唯一约束 我需要验证的密钥是user\u id和sku,但请求不包含user\u id密钥 有效载荷示例: {'sku': '123', data: []} 序列化程序: class ProductConfiguration(serializers.Serializer): min_quantity = serializers.IntegerField(required=True) price = serializers.DecimalFiel

如何使用不在请求负载上的密钥验证唯一约束

我需要验证的密钥是
user\u id
sku
,但请求不包含
user\u id
密钥

有效载荷示例:

{'sku': '123', data: []}
序列化程序:

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']
我需要验证
user
sku
键是否已经存在


默认情况下,如果有效负载上有两个键
user\u id
sku
,则
drf
可以处理
Unique
错误,如果其中一个键不在有效负载上,我如何验证这两个键?

您可以从请求中获取用户数据

请求用户

可能从视图将其传递给序列化程序

data = request.data
data['user_id'] = request.user.pk
serializer = ProductSerializer(data)
在序列化程序中,您可以执行以下操作

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)

假设您有这个模型结构(我只取
sku
user
字段)。为了实现您想要做的事情,在类中meta提供了一个独特的约束

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

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

只需覆盖
validate\u unique
方法即可同时在
user
sku
字段上实现验证

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.',
            )

无需从序列化程序显式验证

问题是,
用户
sku
必须一起验证…这是一个粗略的想法,您可以用来解决问题,至少在最新的django rest framework=3.11.1中,此函数根本不被调用:(
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.',
            )