Django Rest Framework implement update_or_create when deserializing object

I want to implement update_or_create when deserializing object. I found @K-Moe answer in this question: Django Rest Framework POST Update if existing or create

I tried this solution but I got the ValidationError saying that my object already exists:

[{'variant_id': [ErrorDetail(string='sku with this variant id already exists.', code='unique')]}, {'variant_id': [ErrorDetail(string='sku with this variant id already exists.', code='unique')]}]

Did I miss something?

My model

class Sku(models.Model):
    variant_id = models.CharField(primary_key=True, max_length=10, validators=[MinLengthValidator(10)])
    name = models.CharField(max_length=255)
    shop = models.ForeignKey(Shop, related_name='sku', on_delete=models.CASCADE)
    barcode = models.CharField(max_length=60, null=True, blank=True)
    price = models.FloatField(null=True, blank=True)

    def __str__(self):
        return self.name

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['variant_id', 'shop'], name='unique_shop_sku')
            ]

    @classmethod
    def update_or_create(cls, variant_id, shop_id, **kwargs):
        with transaction.atomic():
            return cls.objects.update_or_create(variant_id=variant_id, shop_id=shop_id, defaults=kwargs)

My serializers:

class SkuSerializer(serializers.ModelSerializer):
    shop_id = serializers.CharField(source='shop')

    class Meta:
        model = Sku
        fields = ['name', 'shop_id', 'product_id', 'variant_id', 'barcode', 'price']

    def create(self, validated_data):
        sku = Sku.update_or_create(
            variant_id=validated_data.pop('variant_id'),
            shop_id=validated_data.pop('shop'),
            **validated_data
        )
        return sku
Back to Top