[Fixed]-How to get authenticated user on serializer class for validation

19👍

I found an even easier way of accomplishing this! It turns out that Rest Framework’s GenericAPIView base class (from which all of Rest Framework’s generic View classes descend) includes a function called get_serializer_context():

def get_serializer_context(self):
    """
    Extra context provided to the serializer class.
    """
    return {
        'request': self.request,
        'format': self.format_kwarg,
        'view': self
    }

As you can see, the returned context object contains the same request object that the View receives. This object then gets set when the serializer is initialized:

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)

Thus to access the user who made the request, you just need to call self.context['request'].user from within your Serializer’s validate_ function:

class TemplateSerializer(serializers.ModelSerializer):
    def validate_parent(self, value):
        print(self.context['request'].user)

        return value

    class Meta:
        model = Template

And the best part is that you don’t have to override anything in your ModelViewSet, they can stay as simple as you want them to:

class TemplateViewSet(viewsets.ModelViewSet):
    serializer_class = TemplateSerializer
    permission_classes = [IsAdmin]

7👍

In your views when you initialize serializer like

serializer = ChildUserSerializer(data=request.DATA,context={'request':request})

,send a context which contains request.Then in Serializers inside function call

request=self.context['request']

Then you can access request.user.

5👍

You can pass additional context to your serializer with serializer = ChildUserSerializer(data, context={'request': request}). You can then access the authenticated user via request.user within your serializer validation method.

3👍

In djangorestframework > 3.2.4 the rest_framework.generic.GenericAPIView class includes the http request by default in the serializer context.

So inside your serializer you can access it by: self.context['request'] and the user self.context['request'].user

So your ChildUserSerializer will look like:

class ChildUserSerializer(serializers.ModelSerializer):
    mobile_number = serializers.CharField()
    ....
    def validate(self, data):
        """
        Check that the start is before the stop.
        """
        # Get authenticated user for raise hit limit validation
        user = self.context['request'].user
        # do something with the user here
    def validate_email(self, value):
        if User.objects.filter(email=value):
            raise serializers.ValidationError("This field must be unique.")
        return value
    ...

Leave a comment