【问题标题】:Django : profile edition set_password()Django:配置文件版本 set_password()
【发布时间】:2020-07-04 21:16:06
【问题描述】:

我想为移动应用程序创建一个 API。在这个应用程序中,我们可以创建一个帐户,当然,还可以编辑我们的个人资料。 为了创建一个帐户,我使用 django 帐户默认模型,如下所示: models.py

    def create_user(self, email, username, phone, deliveryAddress, postalCode, city, password=None):
        if not email:
            raise ValueError("Users must have an email address")
        if not username:
            raise ValueError('Users must have an username')
        if not phone:
            raise ValueError('Users must have a phone number')
        if not deliveryAddress:
            raise ValueError('Users must have a delivery Address')
        if not postalCode:
            raise ValueError("Users must have a postal code")
        if not city:
            raise ValueError('Users must have a city')

        user = self.model(
            email = self.normalize_email(email),
            username = username,
            phone = phone,
            deliveryAddress = deliveryAddress,
            postalCode = postalCode,
            city = city,
        )

        user.set_password(password)
        user.save(using = self._db)
        return user

    def create_superuser(self, email, username, phone, deliveryAddress, postalCode, city, password=None):

        user = self.create_user(
            email = self.normalize_email(email),
            username = username,
            password = password,
            phone = phone,
            deliveryAddress = deliveryAddress,
            postalCode = postalCode,
            city = city,
        )

        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using = self._db)

class memberArea(AbstractBaseUser):
    username = models.CharField(max_length=255)
    email = models.EmailField(max_length=255, unique=True)
    phone = models.TextField()
    date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
    deliveryAddress = models.TextField()
    postalCode = models.CharField(max_length=255)
    forget = models.TextField(null=True, blank=True)
    city = models.CharField(max_length=255)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'phone', 'deliveryAddress', 'postalCode', 'city']

    objects = MyAccountManager()

    def __str__(self):
        return self.email + ' : ' + self.username

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

创建帐户时,我会自动使用 set_password() 加密用户密码 现在,我想创建一个视图来编辑一个帐户。 当然,我也希望密码被加密。 这是我的代码: serializer.py

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = memberArea
        fields = ['username', 'email', 'phone', 'password', 'deliveryAddress', 'postalCode', 'city']
        extra_kwargs = {
            'password': {'write_only': True},
        }

views.py

#Edit account
@api_view(['PUT', ])
def edit_account(request, pk):
    try:
        account = memberArea.objects.get(pk=pk)
    except memberArea.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == 'PUT':
        serializer = AccountSerializer(account, data=request.data)
        data = {}
        if serializer.is_valid():
            serializer.save()
            data['response'] = 'Account updated with success !'
            return Response(data)
        return Response(serializer.errors)

在更新个人资料之前,我不知道在哪里以及如何加密密码。 也许我可以通过找到我们要编辑的帐户在我的序列化程序文件中执行此操作,但我不知道如何在此文件中执行此操作... 提前感谢您的帮助

【问题讨论】:

    标签: python django api django-rest-framework django-serializer


    【解决方案1】:

    您可以在序列化程序中执行Field-level validation 将原始密码加密为散列密码。

    以下是在 AccountSerializer 中加密原始密码的示例。然后,来自请求的 json 有效负载的每个原始密码都将被加密为散列密码。

    from django.contrib.auth.hashers import make_password
    
    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = memberArea
            fields = ['username', 'email', 'phone', 'password', 'deliveryAddress', 'postalCode', 'city']
            extra_kwargs = {
                'password': {'write_only': True},
            }
    
        def validate_password(self, raw_password):
            return make_password(raw_password)
    

    【讨论】:

    • 我尝试将您的代码添加到我的代码中,但是当我运行我的代码时,密码已更改但仍未加密
    • “密码已更改但未加密”是什么意思?能举个例子吗?
    • 例如,如果我的密码是'azerty',在数据库中,我就能看到密码是'azerty'
    • 注意:加密是将信息转换为隐藏信息真实含义的密码的方法。使用加密,您无法在数据库中看到用户的原始密码。而是存储散列值(原始密码的密码)。
    • 谢谢,我会检查你的链接。但是使用 AbstractBaseUser 是不是一种编辑我的个人资料(和我的密码)的简单方法?
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 2016-01-05
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    相关资源
    最近更新 更多