Friday, February 23, 2018

Using Django forms to validate POST data in Rest Framework

Django Rest Framework already has a couple of ways to validate data. I believe the "preferred" way is to validate data from serializers. For example:


from rest_framework import serializers

class SomeSerializer(serializers.ModelSerializer):

    def validate(self, data):
        errors = {}
        year_built = data.get('year_built')
        year_rennovated = data.get('year_rennovated')
        
        if year_rennovated < year_built:
            errors['error'] = "You can't renovate something that doesn't exist!"
            raise serializers.ValidationError(errors)
            
        return data

But you can use Django forms, especially if you have existing ones that have the same "shape" of your post data.

Here's an example form:

from django import forms

class BuildingForm(forms.Form):

    year_built = forms.IntegerField(required=True)
    year_rennovated = forms.IntegerField(required=True)
                            
    def clean(self):
        cleaned = super(BuildingForm, self).clean()
        year_built =  cleaned.get('year_built')
        year_rennovated =  cleaned.get('year_rennovated')

        if year_rennovated < year_built:
            raise forms.ValidationError(u'Oops!')


And then in our API View:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class BuildingView(APIView):
    def get(self, request):
        model_form = forms.BuildingForm(request.data)
        if model_form.is_valid():
            data = serializers.someSerializer(obj).data
            return Response(data, status=status.HTTP_200_OK)
        else:
            return Response({'errors': model_form.errors}, status=status.HTTP_400_BAD_REQUEST)