【问题标题】:Change Passwod API using Django Custom user model and serializer使用 Django 自定义用户模型和序列化程序更改密码 API
【发布时间】:2019-04-28 19:38:14
【问题描述】:

我有一个 Django 应用程序,我已经扩展了用户模型并创建了一个用于注册/登录的自定义用户模型,现在我想实现一个更改密码 API,它将用于 Android/IOS 应用程序开发。我会得到参数:

user_id, old_password, new_password

使用这些参数和自定义用户模型和序列化器有什么方法可以实现这一点。

我已经为此尝试了一个示例,但它失败了。

自定义模型:

    class User(AbstractBaseUser, PermissionsMixin):
    objects = UserManager()

    name = models.CharField(max_length=100, blank=True, null=True)
    email = models.EmailField(unique=True)
    created_at = models.DateField(blank=True, null=True, auto_now=True)
    phone_no = models.CharField(max_length=14, blank=True, null=True)
    user_android_id = models.CharField(max_length=255, blank=True, null=True)
    user_fcm_token = models.CharField(max_length=255, blank=True, null=True)
    user_social_flag = models.IntegerField(blank=True, null=True)
    user_fb_id = models.CharField(max_length=255, blank=True, null=True)
    user_android_app_version = models.CharField(max_length=25, blank=True, null=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    USERNAME_FIELD = 'email'

    def __str__(self):
        return self.email

用户管理器:

class UserManager(BaseUserManager):
    use_in_migrations = True

    def create_user(self, email, name, phone_no, created_at, user_android_id, user_fcm_token,
                    user_social_flag, user_fb_id, user_android_app_version, password=None):
        cache.clear()
        user = self.model(
            email=self.normalize_email(email),
            phone_no=phone_no,
            created_at=created_at,
            user_android_id=user_android_id,
            user_fcm_token=user_fcm_token,
            user_social_flag=user_social_flag,
            user_fb_id=user_fb_id,
            user_android_app_version=user_android_app_version,
            name=name,
        )
        user.is_admin = False
        user.is_staff = True
        user.is_superuser = False
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, name, created_at, phone_no, user_android_id, user_fcm_token,
                         user_social_flag, user_fb_id, user_android_app_version, password):
        cache.clear()
        user = self.create_user(
            email,
            # password=password,
            created_at=created_at,
            phone_no=phone_no,
            user_android_id=user_android_id,
            user_fcm_token=user_fcm_token,
            user_social_flag=user_social_flag,
            user_fb_id=user_fb_id,
            user_android_app_version=user_android_app_version,
            name=name,
        )
        user.set_password(password)
        user.is_staff = True
        user.is_admin = False
        user.is_superuser = False
        user.save(using=self._db)
        return user


    def create_superuser(self, email, password):
        cache.clear()
        user = self.model(
            email=self.normalize_email(email),
            # password=password,
            # phone_no=phone_no,
            # created_at=created_at,
            # user_android_id=user_android_id,
            # user_fcm_token=user_fcm_token,
            # user_social_flag=user_social_flag,
            # user_fb_id=user_fb_id,
            # user_android_app_version=user_android_app_version,
            # name=name,
        )
        user.set_password(password)
        user.is_admin = True
        user.is_staff = False
        user.is_superuser = True
        user.save(using=self._db)
        return user

自定义用户序列化器:

class CustomRegisterSerializer(RegisterSerializer):
    email = serializers.EmailField(required=False)
    password1 = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    name = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    phone_no = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    user_android_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    user_fcm_token = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    user_social_flag = serializers.IntegerField(required=False, allow_null=True)
    user_fb_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    user_android_app_version = serializers.CharField(required=False, allow_null=True, allow_blank=True)
    # created_at = serializers.DateField(format="%Y-%m-%d", input_formats=['%Y-%m-%d', 'iso-8601'])

    class Meta:
        model = User
        fields = ('email', 'password', 'name', 'phone_no', 'user_android_id', 'user_fcm_token',
                  'user_social_flag', 'user_fb_id', 'user_android_app_version')


    def get_cleaned_data(self):
        super(CustomRegisterSerializer, self).get_cleaned_data()

        return {
            'password1': self.validated_data.get('password1', ''),
            'email': self.validated_data.get('email', ''),
            'phone_no': self.validated_data.get('phone_no', ''),
            'name': self.validated_data.get('name', ''),
            'user_android_id': self.validated_data.get('user_android_id', ''),
            'user_fcm_token': self.validated_data.get('user_fcm_token', ''),
            'user_social_flag': self.validated_data.get('user_social_flag', ''),
            'user_fb_id': self.validated_data.get('user_fb_id', ''),
            'user_android_app_version': self.validated_data.get('user_android_app_version', ''),

        }

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user

更改密码 API:

class CustomChangePasswordView(APIView):
    """
        User Change Password API
    """
    def post(self, request):
        data = request.data
        u_id = data.get('user_id')
        old_password = data.get('user_old_password')
        new_password = data.get('user_new_password')

        user = User.objects.get(id=u_id)

        if user.password != old_password:
            return Response({"msg":"Invalid Old Password"}, status=status.HTTP_200_OK)
        else:
            user.set_password(new_password)
            return Response({"msg":"Change successfull!"}, status=status.HTTP_201_CREATED)

我得到的错误响应:

{
"msg": "Invalid Old Password"
}

我错过了什么?

还有其他更好的方法吗?

【问题讨论】:

    标签: django api django-rest-framework django-custom-user


    【解决方案1】:

    更新CustomChangePasswordView 代码如下:

    if user.check_password(old_password):
         user.set_password(new_password)
         user.save()
         return Response({"msg":"Change successfull!"}, status=status.HTTP_201_CREATED)
    else:
         return Response({"msg":"Invalid Old Password"}, status=status.HTTP_200_OK)
    

    您可以在here查看有关检查密码的文档。

    【讨论】:

    • 这也进入else部分并返回“无效的旧密码”
    • 在这种情况下,请检查old_password 变量中的密码是否正确。 (也许通过print(old_password)
    • 是的,正确,问题出在参数名称上。谢谢。
    • 我在这里遇到问题,当用户使用社交帐户登录时,密码为空。一旦数据库中的密码为空并且我尝试使用上述方法更新,密码没有得到更新。为什么?
    • 您需要调用user.save()来存储密码。对不起,我之前错过了。请查看我的更新答案
    猜你喜欢
    • 2016-08-08
    • 2020-04-20
    • 1970-01-01
    • 2019-10-07
    • 2018-02-04
    • 2013-02-24
    • 2018-12-10
    • 1970-01-01
    • 2013-05-10
    相关资源
    最近更新 更多