0

我正在使用自定义用户身份验证模型,该模型使用电子邮件地址作为用户名并创建用户,但即使密码 1 与密码 2 不同,注册也会成功完成。我无法调试问题。

这是models.py文件:

class UserManager(auth_models.BaseUserManager):
    def create_user(self, email, first_name, last_name, password):
            """
                Creates and saves a user with given email,
                first name, last name and password.
            """
            if not email:
                    raise ValueError("users must have an email address")

            user = self.model(
                    email=UserManager.normalize_email(email),
                    first_name=first_name,
                    last_name=last_name,
            )
            user.set_password(password)
            user.save(self._db)
            return user

    def create_superuser(self, email, first_name, last_name, password):
            """
                Creates and saves a super_user with given email,
                first name, last name and password.
            """
            if not email:
                    raise ValueError("users must have an email address")

            user = self.model(
                    email=UserManager.normalize_email(email),
                    first_name=first_name,
                    last_name=last_name,
            )
            user.is_admin = True
            user.set_password(password)
            user.save(self._db)
            return user



class User(auth_models.AbstractBaseUser):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    joined_at = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()

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

    def get_full_name(self):
            return self.first_name + " " + self.last_name

    def get_short_name(self):
            return self.first_name

    def __str__(self):
            return self.get_full_name() + ", email= " + self.email

    @property
    def is_staff(self):
            return self.is_admin

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

    def has_module_perms(self, app_label):
            return True

    class Meta:
            verbose_name_plural = "users"

管理员.py

class UserCreationForm(forms.ModelForm):
    """
        A form for creating new users. Includes all the required
        fields, plus a repeated password.
    """

    password1 = forms.CharField(label='password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='confirm password', widget=forms.PasswordInput)

    class Meta:
            model = User
            fields = ('first_name', 'last_name', 'email')

    def clean_password(self):
            """
                check that the two password entries match
            """
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                    raise forms.ValidationError("passwords don't match")
            return password2

    def save(self, commit=True):
            user = super(UserCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                    user.save()
            return user


class UserChangeForm(forms.ModelForm):
    """
        A form for updating users. includes all the fields
        on the user, but replaces the password field with
        the admin's password hash display field.
    """

    password = ReadOnlyPasswordHashField()

    class Meta:
            model = User
            fields = ('first_name', 'last_name', 'email', 'password', 'is_active', 'is_admin')

    def clean_password(self):
            """
                Regardless of what the user provides, return the initial value.
                This is done here, rather than on the field, because the field
                does not have access to the initial value.
            """
            return self.initial["password"]

视图.py

def register(request):
    args = {}
    args.update(csrf(request))
    if request.method == 'POST':
            form = UserCreationForm(request.POST)
            args['form'] = form
            if form.is_valid():
                    form.save()
                    return HttpResponseRedirect('/home/')
    else:
            args['form'] = UserCreationForm()
    return render_to_response('authentication/signup.html', args, context_instance=RequestContext(request))
4

2 回答 2

1

clean_password()尝试将函数clean()中存在的密码比较逻辑移动到UserCreationForm.

clean_fieldname()函数应在该字段上运行,fieldname而不是在任何其他字段上运行。

此外,当字段验证相互依赖时,放置验证逻辑的最佳位置是clean()方法内部。

来自Django 文档:

我们一次对多个字段执行验证,因此表单的clean()方法是执行此操作的好地方。

到调用表单的clean()方法时,所有单独的字段清理方法都将运行(前两节),因此 self.cleaned_data将填充迄今为止存活的任何数据。因此,您还需要记住要考虑到您要验证的字段可能无法通过初始单个字段检查的事实。

代码:

class UserCreationForm(forms.ModelForm):
    ...

    def clean(self):
        cleaned_data = super(UserCreationForm, self).clean()
        password1 = cleaned_data.get("password1")
        password2 = cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("passwords don't match")
        return cleaned_data 
于 2015-10-04T17:07:26.480 回答
0

问题是,您没有“密码”字段,您需要将方法名称更改为clean_password1 或 clean_password2。

您创建的方法clean_password永远不会被调用,因为没有名为 password 的字段

def clean_password1(self):
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError("passwords don't match"")
    return password1
于 2015-10-04T17:23:15.267 回答