问题
I have 2 models : User & UserSummary. UserSummary has a foreign key to User. I just noticed that if I set depth= 1
within UserSummarySerializer
, the password field is included in the output. It's hashed, but it would still be best to exclude this field.
To hide the password field, I've just set the user field explicitly in the serializer, just like this :
class UserSerializer(serializers.ModelSerializer):
"""A serializer for our user profile objects."""
class Meta:
model = models.User
extra_kwargs = {'password': {'write_only': True}}
exclude = ('groups', 'last_login', 'is_superuser', 'user_permissions', 'created_at')
def create(self, validated_data):
"""Create and return a new user."""
user = models.User(
email = validated_data['email'],
firstname = validated_data['firstname'],
lastname = validated_data['lastname'],
mobile = validated_data['mobile']
)
user.set_password(validated_data['password'])
user.save()
return user
class UserSummarySerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = models.UserSummary
fields = '__all__'
depth = 1
The downside of this way of doing is that, the field password is not available anymore on the POST request when creating a new user.
How could I hide the password
field on the GET request of UserSummary but display it in the POST request of User ?
回答1:
This is complicated when you put all the function serializer to one, I would create a UserCreateSerializer
in this scenario:
class UserCreateSerializer(serializers.ModelSerializer):
"""A serializer for our user profile objects."""
class Meta:
model = models.User
extra_kwargs = {'password': {'write_only': True}}
fields = ['username', 'password', 'email', 'firstname', 'lastname', 'mobile'] # there what you want to initial.
def create(self, validated_data):
"""Create and return a new user."""
user = models.User(
email = validated_data['email'],
firstname = validated_data['firstname'],
lastname = validated_data['lastname'],
mobile = validated_data['mobile']
)
user.set_password(validated_data['password'])
user.save()
return user
Then you can use the UserCreateSerializer
in your UserCreateAPIView
.
回答2:
The trick here is to include the 'password' field in the "fields" tuple so that password shows in BOTH 'GET' and 'POST', and then add 'extra_kwargs' to force 'password' field ONLY to appear in 'POST' form. Code as below:
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email',
'is_active', 'is_staff', 'is_superuser', 'password',)
# These fields are displayed but not editable and have to be a part of 'fields' tuple
read_only_fields = ('is_active', 'is_staff', 'is_superuser',)
# These fields are only editable (not displayed) and have to be a part of 'fields' tuple
extra_kwargs = {'password': {'write_only': True, 'min_length': 4}}
回答3:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
def to_representation(self, obj):
rep = super(UserSerializer, self).to_representation(obj)
rep.pop('password', None)
return rep
回答4:
To Make your password to not show password, you need to change style like following-
password = serializers.CharField(
style={'input_type': 'password'}
)
That's it. I hope it helps.
来源:https://stackoverflow.com/questions/48480972/hide-password-field-in-get-but-not-post-in-django-rest-framework-where-depth-1-i