Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework best way to validate POST request parameters

When I receive a POST request on a Django REST framework APIView class, I would like to filter/validate the parameters that are passed to prevent them from being modified. For example, for this serializer:

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Media
        fields = ('id', 'title', 'content', 'url', 'createdByUser', 'karma', 'type', 'issue', 'creationDate', 'updatedDate')

Some parameters such as the id, creationDate or createdByUser shouldn't be modified. So for my class class MediaDetail(APIView) I have:

def validateRequest(self):
        user = self.request.data.get('createdByUser', None)
        karma = self.request.data.get('karma', None)
        creationDate = self.request.data.get('creationDate', None)

        if user is not None or karma is not None or creationDate is not None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

@method_decorator(login_required)
def post(self, request, pk, format=None):
        self.validateRequest()
        media = self.get_object(pk)
        self._throwIfNotMediaAuthor(media, request.user)

        serializer = MediaSerializer(media, data=request.data)

        if serializer.is_valid():
            # serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Is there a better way to make this validation? Maybe on the serializer? I couldn't find enough documentation.

like image 523
selan Avatar asked Feb 25 '19 13:02

selan


People also ask

Which authentication is best in Django REST framework?

JSON Web Token (JWT) Authentication This is a new and popular standard that works similar to TokenAuthentication except that it does not need to save tokens in the database.

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.


1 Answers

Yes, you can use the read_only_fields parameter on your serializer's Meta.

Example on how to use inside your current view (modified it a little assuming you want to create an object when POSTing as per REST's guidelines):

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Media
        read_only_fields = ('id', 'karma', 'createdByUser', 'creationDate')
        ...

@method_decorator(login_required)
def post(self, request, pk, format=None):
        serializer = MediaSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(createdByUser=request.user, creationDate=timezone.now().date(), karma=initial_value)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
like image 115
henriquesalvaro Avatar answered Sep 21 '22 05:09

henriquesalvaro