我使用DRFModelViewSet进行用户帐户CRUD操作。我用Profile模型“扩展”Django用户模型来存储补充的用户信息。我在序列化器中覆盖了create和update方法来管理Profile模型的嵌套(相关)字段。
使用GET和POST方法是可以的。在POST中,密码被正确地创建并存储(加密的PBKDF2)在我的PostgreSQL数据库中。
我的问题涉及PUT和PATCH方法。当使用PATCH或PUT方法时,提交password和password2时,password以明文形式存储在数据库中。
我试着使用make_password()和set_password(make_password()),但都不起作用。我读过DRF文档,也读过SO中的许多帖子,但找不到任何解释。
希望有人能解释这种行为,也许可以解决这个问题。
Serializers.py
class RegisterSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(required=True)
email = serializers.EmailField(required=True,validators=[UniqueValidator(queryset=User.objects.all())])
password = serializers.CharField(write_only=True, required=True, validators=[validate_password])
password2 = serializers.CharField(write_only=True, required=True)
days_since_joined = serializers.SerializerMethodField()
class Meta:
model = User
fields = ('username', 'password', 'password2', 'email', 'first_name', 'last_name', 'profile', 'days_since_joined')
extra_kwargs = {
'first_name': {'required': True},
'last_name': {'required': True}
}
def validate(self, attrs):
password = attrs.get('password')
password2 = attrs.get('password2')
if password and password != password2:
raise serializers.ValidationError({"password": "Password fields didn't match."})
return attrs
def get_days_since_joined(self, obj):
return (now() - obj.date_joined).days
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(
username=validated_data['username'],
email=validated_data['email'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name']
)
# create profile
Profile.objects.create(
user=user,
qr_code=profile_data.get('qr_code'),
backup=profile_data.get('backup'),
role_in_study=profile_data.get('role_in_study'),
)
user.set_password(validated_data['password'])
user.save()
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile', {})
profile = instance.profile
for key, value in profile_data.items():
setattr(profile, key, value)
profile.save()
return super().update(instance, validated_data)
1条答案
按热度按时间ylamdve61#
我认为你在
update
方法中缺少了set_password
。