Django Rest Framework - validating / manipulating data (by some logic) before storing in the database

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 views.py

class ReviewViewSet(viewsets.ModelViewSet):
    """
    College API
    """
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
    paginate_by = 5

      

Now, whenever I submit something to the API, it is directly saved to the database if the validation is successful. I need, I want to validate and apply some conditions to the data using some business logic before it stores the data in the database. So if the condition is true only then the data is saved or it returns an error message to the client.

+3


source to share


2 answers


You can overwrite the default create method in ModelViewSet. This method is called when you post (POST http method) something to your API. Then you can check if the serialized data is valid and then apply your business logic while storing it:



class ReviewViewSet(viewsets.ModelViewSet):
    """
    College API
    """
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
    paginate_by = 5

    def create(self, request):
        serializer = ReviewSerializer(data=request.DATA)
        if serializer.is_valid():

            #YOUR CODE HERE

            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

      

+2


source


I am assuming you are using the newer version 3.0. Then you need to put your validation logic in your serializer ReviewSerializer

(see http://www.django-rest-framework.org/topics/3.0-announcement/#serializers ).

So, if you want to create a field validation, you must overload def validate_<fieldname>(self, value)

. For example, if you want to Review.placements

be >= 0.0

, you can 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 want a more perfect check eg. to check two dependent fields you need to override def validate(self, attrs)

.



For example, to 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 add some objects on top of the REST API, the validation will be called automatically. You don't need to override methods ModelViewSet

.

The link above and www.django-rest-framework.org/api-guide/serializers/#validation more hints.

+3


source







All Articles