djangodjango-rest-framework

May not set both `read_only` and `write_only`


In my project I want to set password as both read_only(because I have a separate endpoint to reset password) and write_only(because I don't want password send in the response).

Here is my serializer:

class UserSerializer(serializers.ModelSerializer):
    """A Serizlier class for User """

    class Meta:
        model = models.User
        fields = ('id', 'email', 'phone_number', 'user_type', 'password')
        extra_kwargs = { 'password': { 'write_only': True} }
        read_only_fields = ('password',)

But I get an error saying:

AssertionError at /api/user/21/

May not set both read_only and write_only

How can I have a field be both read_only and write_only?


Solution

  • Override the __init__() method of the serializer as,

    class UserSerializer(serializers.ModelSerializer):
        """A Serizlier class for User """
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            if self.context['some_flag']:
                self.fields['password'].read_only = True
            else:
                self.fields['password'].write_only = True
    
        class Meta:
            model = models.User
            fields = ('id', 'email', 'phone_number', 'user_type', 'password')
            # extra_kwargs = { 'password': { 'write_only': True} } # remove this
            # read_only_fields = ('password',) # remove this

    The some_flag variable is something that you should pass to the serializer either from the password reset view or from the other view