You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义注册表单无法拦截短纯数字密码的问题该如何解决?

问题根因
  • 校验方法命名不符合Django规则:你定义的密码校验方法名为clean_password,但实际密码字段的名称是password1,Django表单的单字段校验方法必须遵循clean_<字段名>的命名规则才会被自动调用,因此你写的密码校验逻辑完全没有生效。
  • 若未在项目配置中启用对应密码校验规则,即使校验方法执行,也不会拦截纯数字、过短的密码。
修复步骤

1. 修正表单校验方法

将forms.py中的clean_password方法改名为clean_password1,匹配字段名让校验逻辑可以被正常触发:

# forms.py 修改后的对应代码
from django.core.exceptions import ValidationError

class RegisterUserForm(forms.ModelForm):
    # 原有字段定义保持不变
    email = forms.EmailField(required=True, label='Адрес электронной почты')
    password1 = forms.CharField(label='Пароль',
                                widget=forms.PasswordInput,
                                help_text=password_validation.password_validators_help_text_html())
    password2 = forms.CharField(label='Пароль повторно',
                                widget=forms.PasswordInput,
                                help_text='Введите тот же самый пароль ещё раз для проверки')
    captcha = CaptchaField(label='Введите текст с картинки ', error_messages={'invalid': 'Неправильный текст'}, generator='captcha.helpers.math_challenge')

    # 方法名修改为clean_password1,匹配字段名
    def clean_password1(self):
        password1 = self.cleaned_data['password1']
        if password1:
            # 调用Django内置密码校验,会自动执行settings中配置的所有校验规则
            password_validation.validate_password(password1)
            # 如果你不想改全局配置,也可以直接在这里加自定义校验
            # if len(password1) < 8:
            #     raise ValidationError("密码长度不能少于8位")
            # if password1.isdigit():
            #     raise ValidationError("密码不能仅由数字组成")
        return password1

    # 其余原有方法(clean、save、Meta类)保持不变
    def clean(self):
        super().clean()
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            errors = {'password2': ValidationError(
                'Введённые пароли не совпадают', code='password_mismatch')}
            raise ValidationError(errors)

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

    class Meta:
        model = AdvUser
        fields = ('username', 'email', 'password1', 'password2', 'first_name', 'last_name', 'photo', 'description', 'captcha')

2. 配置全局密码校验规则(可选,推荐)

在项目settings.py中找到AUTH_PASSWORD_VALIDATORS配置项,添加Django自带的最小长度校验、纯数字禁止校验,规则会全局生效,所有调用password_validation.validate_password的地方都会自动执行:

# settings.py
AUTH_PASSWORD_VALIDATORS = [
    # 保留原有配置的校验器,比如用户相似度校验、常用密码校验等
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    # 新增/修改最小长度校验
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 8, # 可自行调整最小长度阈值
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    # 新增纯数字密码禁止校验
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

配置完成后,password1字段自带的help_text会自动生成对应的规则提示给前端用户,无需额外修改。

内容的提问来源于stack exchange,提问作者ilsurealism

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:48:02