1

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?

Abishek
  • 369
  • 4
  • 21

1 Answers1

3

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.')
Aprimus
  • 1,463
  • 1
  • 14
  • 12
  • Is there a way to highlight the name field in the browsable API in red when the validation occurs?, Mimicking the default validation. – Abishek Apr 08 '21 at 19:11