Django:个人资料版set_password()

时间:2020-07-04 12:48:13

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

我想为移动应用程序创建一个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)

在更新配置文件之前,我不知道在哪里以及如何加密密码。 也许我可以在序列化器文件中找到想要编辑的帐户,以完成此操作,但是我不知道如何在此文件中执行此操作... 在此先感谢您的帮助

1 个答案:

答案 0 :(得分: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)