I just noticed that if you set the depth option to >= 1 and the model has a foreign key to django.contrib.auth.models.User, the password field is included in the output. It's hashed, but it would still be best to exclude this field.
password on django.contrib.auth.models.User is just a regular CharField with no special markup to indicate that it's special in any way.
The only way we could deal with this feature request would be to special case that one particular field for that one particular model. That's not something I want us to do.
I'd strongly suggest using fields=... or exclude=... to remove it from the serializer class instead.
I'd suggest to have a password field added to django instead,
I used the following field in the past.
class PasswordField(serializers.CharField):
def __init__(self, *args, **kwargs):
kwargs['write_only'] = True
super(PasswordField, self).__init__(*args, **kwargs)
def from_native(self, value):
return make_password(value)
The solution is to always specify how to serialize the user object and use this field or exclude it from the serializer.
From a security perspective I believe you are right and we should at the very least warn about it in the docs.
@tomchristie For my normal User serializers, I do use the exclude field to remove the password.
However, in this case it is being automatically added by NestedModelSerializer returned by Serializer.get_nested_field.
Since it is dynamically generating a Serializer for the nested field, I don't have the opportunity to exclude the field.
Perhaps an argument on the Serializer Fields indicating which Serializer should be used if nested....?
That's way too complex.
So you need to set the user field explicitly in that case...
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
exclude = ('password',)
class SomeOtherThingSerializer(serializers.ModelSerializer):
user = UserSerializer() # Declare this field explicitly.
class Meta:
model = SomeOtherThing
depth = 1
Thank You, you help me :) and i have a ManyToMany relations, i share with us my code for ManyToMany :) with Django Rest Framework:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
exclude = (
'password', 'last_login', 'is_superuser', 'email',
'gender', 'verify_code', 'created_on', 'is_active',
'is_staff', 'groups', 'user_permissions', 'courses'
)
class ResponseCommentSerializer(serializers.ModelSerializer):
user_response = UserSerializer()
class Meta:
model = ResponseComment
fields = '__all__'
depth = 1
class CommentSerializer(serializers.ModelSerializer):
user = UserSerializer()
response = ResponseCommentSerializer(many=True, read_only=True)
class Meta:
model = Comment
fields = '__all__'
depth = 2
What is the depth? Many thanks for your help.
What is the depth? Many thanks for your help.
@mrParabol "Depth" is to show the detail data of your relations, for example if you have a user relation in your model and if you don't have depth you can only show the user id, but if you need the "relation detail" you need add depth, you can try it with a relation, if you need show more than 1 relation, add depth=(number of relations to show)
Most helpful comment
So you need to set the user field explicitly in that case...