3👍
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
2👍
So extending on the answer of @JPG
The Serializer
class ProfileSerializer(serializers.ModelSerializer):
name = serializers.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'create_method' in self.context:
self.fields['name'].write_only = True
else:
self.fields['name'].read_only = True
And the view set
class ProfileViewSet(viewsets.ModelViewSet):
serializer_class = ProfileSerializer
def get_serializer_context(self):
# Call Parent
context = super().get_serializer_context()
# Check If This Is a POST
if self.request.method == 'POST':
context['create_method'] = True
# Handoff
return context
This will allow name to be written on POST and read only on everything else
0👍
well – normally if you have two endpoints using a similar serializer which needs to differ only with a certain field/functionality you would create a base class and abstract it and only change/modify the parts of it that need to change. Here is what I would do.
class (serializers.ModelSerializer):
"""A Serizlier class for User """
class Meta:
model = models.User
fields = ('id', 'email', 'phone_number', 'user_type', 'password')
extra_kwargs = { 'password': { 'read_only': True} }
class UserSerializerForOtherView(UserSerializer):
class Meta(UserSerializer.Meta):
extra_kwargs = { 'password': { 'write_only': True} }
Now UserSerializerForOtherView
inherits the same behaviour as UserSerializer
and you now also have a new serializer should you want to further expand on functionality on this serializer alone.
All you will need to do is tell the other view to use the other serializer.