Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework: Unique_together validation on Serializers

Tags:

Having issues with a serializer.is_valid() returning True if the serializer instance fails a unique_together constraint on the model side.

Is there a way for me to specify in the serializer to enforce a unique_together constraint?

like image 211
fangsterr Avatar asked Mar 24 '14 21:03

fangsterr


People also ask

How does Django validate data in serializer?

Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class. With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class.

Do we need Serializers in Django REST framework?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

How do I know if my serializer is valid?

We can validate the serializer by calling the method " is_valid() ". It will return the boolean(True/False) value. If the serializer is not valid then we can get errors by using the attribute "errors".

How do I validate an email in Django REST framework?

This can be easily done by automatically sending the verification email with an activation link. Such a link contains the unique token assigned to the user. After opening the activation link in the web browser the request is sent to the web application (Django Rest Framework).


1 Answers

The ModelSerializer class has this functionality build-in, at least in djangorestframework>=3.0.0, however if you are using a serializer which doesn't include all of the fields which are affected by your unique_togetherconstrain, then you'll get an IntegrityError when saving an instance which violates it. For example, using the following model:

class Foo(models.Model):     class Meta:         unique_together = ('foo_a', 'foo_b')      a = models.TextField(blank=True)     b = models.TextField(blank=True)     foo_a = models.IntegerField()     foo_b = models.IntegerField(default=2) 

and the following serializer and ViewSet:

class FooSerializer(serializers.ModelSerializer):     class Meta:         model = models.Foo         fields = ('a', 'b', 'foo_a')  class FooViewSet(viewsets.ModelViewSet):     queryset = models.Foo.objects.all()     serializer_class = FooSerializer   routes = routers.DefaultRouter() routes.register(r'foo', FooViewSet) 

if you try to save two instances with the same foo_a and foo_b set, you'll get an IntegrityError. However, if we modify the serializer like this:

class FooSerializer(serializers.ModelSerializer):     class Meta:         model = models.Foo         fields = ('a', 'b', 'foo_a', 'foo_b') 

you'll then get a proper HTTP 400 BAD REQUEST status code, and the corresponding JSON descriptive message in the response body:

HTTP 400 BAD REQUEST Content-Type: application/json Vary: Accept Allow: GET, POST, HEAD, OPTIONS  {     "non_field_errors": [         "The fields foo_a, foo_b must make a unique set."     ] } 

I hope this to result helpful for you, even when this is a somewhat old-posted question ;-)

like image 158
seorc Avatar answered Sep 29 '22 11:09

seorc