Evan Zamir
Evan Zamir

Reputation: 8481

How to return 400 error for unique_together constraint violation?

I am using Django-Rest-Framework and have a model with the following constraint:

unique_together = ("title", "owner")

When that error is encountered the server sends a 500 response to the client, but I want to return a 400 error and detail of the constraint, so I can show it to the user. Here is the serializer code:

def create(self, validated_data):
    title = validated_data.pop('title')
    poll = Poll.objects.create(title=title,
                               slug=slugify(title),
                               **validated_data)
    p = Poll.objects.get(id=poll.id)
    [p.tags.add(tag) for tag in validated_data['tags']]
    return poll

The owner is coming from the request (i.e. client user):

def perform_create(self, serializer):
    """

    :param serializer:
    :return:
    """
    serializer.save(owner=self.request.user,
                    follows=[])

I'm not sure where to put the validation code.

Upvotes: 2

Views: 1839

Answers (3)

Lance
Lance

Reputation: 995

You can use the built in rest_framework.validators.UniqueTogetherValidator as per the documentation

from rest_framework.validators import UniqueTogetherValidator

class PollSerializer(serializers.Serializer):
    # ...
    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=Poll.objects.all(),
                fields=['owner', 'title']
            )
        ]

Upvotes: 3

neverwalkaloner
neverwalkaloner

Reputation: 47374

You can override serializer's validate method like this:

from rest_framework.exceptions import ValidationError

def validate(self, attrs):
    validated_data = super(WriteoffSerializer, self).validate(attrs)
    poll = Poll.objects.filter(title=validated_data['title'], owner=validated_data['owner').exists()
    if poll:
        raise ValidationError('Poll with such title and owner already exists') 
    return validated_data 

By default this exception results in a response with the HTTP status code "400 Bad Request".

Upvotes: 2

Mazel Tov
Mazel Tov

Reputation: 2192

If your python function throws error you can always catch it with try and except

def create(self, validated_data):
    try:
        # this code throws error
        ...
        return poll
    except Exception as e:
        # i caught error
        return str(e)

Upvotes: 0

Related Questions