I am new to Django Rest Framework. I have a serializer like this:
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = (
'user',
'course',
'major',
'title',
'text',
'placements',
'faculty',
'infrastructure',
'students',
'extra_curricular',
'passing_year',
)
models.py
class Review(models.Model):
user = models.ForeignKey(to=User, related_name='reviews')
course = models.ForeignKey(to=Course, related_name='reviews')
major = models.ForeignKey(to=Major, related_name='reviews', blank=True, null=True)
title = models.TextField(db_index=True)
text = models.TextField(db_index=True)
placements = models.FloatField(default=0.0)
faculty = models.FloatField(default=0.0)
infrastructure = models.FloatField(default=0.0)
students = models.FloatField(default=0.0)
extra_curricular = models.FloatField(default=0.0)
passing_year = models.PositiveSmallIntegerField(default=2014)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
And the views.py
class ReviewViewSet(viewsets.ModelViewSet):
"""
College API
"""
queryset = Review.objects.all()
serializer_class = ReviewSerializer
paginate_by = 5
Now,whenever I post something to the API it directly gets saved to the database if the validation passes successfully. What I need is, I want to check and apply some conditions on the data using some business logic before it saves the data to the database. So that if the condition is true only then the data gets saved, or else it returns a error message to the client.
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
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.
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.
In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.
I assume you are using the new version 3.0. Then you need to put your validation logic into your serializer ReviewSerializer
(See http://www.django-rest-framework.org/topics/3.0-announcement/#serializers).
So if you want to create a validation of the fields you should overload the def validate_<fieldname>(self, value)
. For example if you want Review.placements
be >= 0.0
, you may write
class ReviewSerializer(serializers.ModelSerializer):
[...]
def validate_placements(self, value):
if value >= 0.0:
return value
raise serializers.ValidationError('placements should be non-negative.')
[...]
If you need more advanced validation, e.g. to validate two dependent fields, then you need to override the def validate(self, attrs)
.
For example to have created_on <= updated_on
class ReviewSerializer(serializers.ModelSerializer):
[...]
def validate(self, attrs):
if attrs['created_on'] <= attrs['update_on']:
return attrs
raise ValidationError('Date of creation should be before update date.')
[...]
If you now add some objects over REST-API, the validation will be called automatically. You don't have to override the methods of ModelViewSet
.
In the link above and in www.django-rest-framework.org/api-guide/serializers/#validation are more hints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With