0

電子メール アドレスをユーザー名として使用してユーザーを作成するカスタム ユーザー認証モデルを使用していますが、password1 が password2 と異なっていても、登録は正常に完了します。問題をデバッグできません。

ここに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"

admin.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()メソッドが呼び出されるまでに、すべての個々のフィールドのクリーン メソッドが実行されているため (前の 2 つのセクション)、それ 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 に答える