Search code examples
djangodjango-rest-frameworkdjango-serializerdjango-validationdjango-rest-viewsets

drf ModelViewset does not validate Unique Constraint failed when unique_together is used


I am using djangorestframework==3.12.1 Here is how my code looks like:-

models.py

class Product(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=14, decimal_places=2)
    description = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        unique_together = (
            ("name", "user"),
        )

serializers.py

class ProductSerializer(serializers.ModelSerializer):
    """serializer for Product objects."""

    class Meta:
        model = models.Product
        fields = '__all__'
        read_only_fields = ['user',]

views.py

class ProductViewset(viewsets.ModelViewSet):
    queryset = models.Product.objects.all()
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = serializers.ProductSerializer

Expected Behavior

The validators on the Modelserializers must raise an exception as Product with this Name and User already exists.

Actual Behavior

IntegrityError at /api/v1/product/ UNIQUE constraint failed: projectapp_product.name, projectapp_product.user_id

How do I fix this?


Solution

  • You can try to override the perform_create of ProductViewSet like this:

    class ProductViewset(viewsets.ModelViewSet):
        queryset = models.Product.objects.all()
        permission_classes = [permissions.IsAuthenticated]
        serializer_class = serializers.ProductSerializer
    
        def perform_create(self, serializer):
            user = self.request.user
            try:
                serializer.save(user=user)
            except IntegrityError:
                raise ValidationError('Product with this Name and User already exists.')