【问题标题】:Create a new custom user or upate existing one创建新的自定义用户或更新现有用户
【发布时间】:2016-10-28 14:20:08
【问题描述】:

我创建了一个自定义用户模型:

class CUserManager(BaseUserManager):

    def _create_user(self, email, first_name, password,
                     is_staff, is_superuser, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        now = timezone.now()
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email,
                          first_name = first_name,
                          is_staff=is_staff, is_active=False,
                          is_superuser=is_superuser, last_login=now,
                          date_joined=now, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, first_name, password=None, **extra_fields):
        return self._create_user(email, first_name, password, False, False,
                                 **extra_fields)

    def create_superuser(self, email, first_name, password, **extra_fields):
        return self._create_user(email, first_name, password, True, True,
                                 **extra_fields)


class CUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), max_length=254, unique=True)
    first_name = models.CharField(_('first name'), max_length=30)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(_('active'), default=False,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    last_updated = models.DateTimeField(_('last updated'), default=timezone.now)
    image = ProcessedImageField(upload_to= generate_random_filename,
                                processors=[ResizeToFill(640, 640)],
                                format='JPEG',
                                options={'quality': 60})

    objects = CUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def save(self, *args, **kwargs):
        try:
            this = CUser.objects.get(id=self.id)
            if this.image != self.image:
                this.image.delete()
        except: pass
        super(CUser, self).save(*args, **kwargs)

我的注册序列化器:

class UserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(style={'input_type': 'password'},
                                     write_only=True,
                                     validators=settings.get('PASSWORD_VALIDATORS'))
    class Meta:
        model = User
        fields = tuple(User.REQUIRED_FIELDS) + (
            User.USERNAME_FIELD,
            'image',
            'password',
        )

    def create(self, validated_data):
        if settings.get('SEND_ACTIVATION_EMAIL'):
            with transaction.atomic():
                user = User.objects.create_user(**validated_data)
                user.is_active = False
                user.save(update_fields=['is_active'])
        else:
            user = User.objects.create_user(**validated_data)
        return user

我的注册视图:

class RegistrationView(generics.CreateAPIView):
    serializer_class = serializers.UserRegistrationSerializer
    permission_classes = (
        permissions.AllowAny,
    )

    def perform_create(self, serializer):
        user = serializer.save()
        signals.user_registered.send(sender=self.__class__, user=user, request=self.request)
        if settings.get('SEND_ACTIVATION_EMAIL'):
            self.send_activation_email(user)
        elif settings.get('SEND_CONFIRMATION_EMAIL'):
            self.send_confirmation_email(user)

这会创建一个新用户。但是,当我尝试使用一些已注册的电子邮件访问此端点时,我收到错误消息。而不是这个,我想更新用户条目,以防用户不活跃并想再次注册。我无法弄清楚这一点。我尝试在序列化程序中使用 update() 方法,但它没有用。请帮忙。

【问题讨论】:

    标签: django django-rest-framework django-users


    【解决方案1】:

    我会在序列化程序的 create 方法中执行此操作。

    def create(self, validated_data):
        try:
            user = User.objects.get(email=validated_data['email'])
            // There was already a user with that email, do something
        except User.DoesNotExist:
            user = User.objects.create_user(**validated_data)
            if settings.get('SEND_ACTIVATION_EMAIL'):
                with transaction.atomic():
                    user.is_active = False
                    user.save(update_fields=['is_active'])
    
        return user
    

    【讨论】:

    • 我尝试添加它,但我仍然收到“使用此电子邮件地址的用户已存在”。我尝试将打印语句放在视图的 perform_create() 和序列化程序 create() 中。对于不存在的电子邮件,两个语句都会打印,但对于现有的电子邮件,它们都不会打印。
    • 你能在你的问题中添加这个错误的回溯吗?
    • 没有错误。 “使用此电子邮件地址的用户已经存在。”是返回 400 状态码的响应。
    • 哦,是的,你的模型有一个unique=True 约束,所以你的序列化器在到达create 方法之前验证它。尝试将queryset = User.objects.filter(is_active=True) 添加到您的RegistrationView 中,看看是否仍然出现验证错误。
    • 我仍然得到相同的响应。您能否解释一下为什么在将查询集更改为此之后您希望它能够工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 2019-01-12
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多