如果在 try 块中,则不会引发 ValidationError - 自定义表单域验证器

ValidationError don't raise if in try block - Custom formfield validators

做了什么

我有一个表单可以接收提供给用户的代码,这样他就可以验证他的电子邮件地址。为了检查表单是否有效,我创建了一个自定义字段验证器,请参阅 forms.py

问题

看起来如果 raise ValidationError("...") 总是会在 try 块中失败。这是正常行为还是我做错了什么?

forms.py

class SignUpVerificationForm(forms.Form):

    def is_valid_verification_code(code):
        #settings
        time_to_verify_in_minutes = 5

        try:
            tmp = SignUpUser.objects.get(signup_verification=code)
            email = tmp.signup_email
            time = tmp.signup_time
            if time >= timezone.now() - datetime.timedelta(minutes=time_to_verify_in_minutes):
                try:
                    check = User.objects.get(email=email)
                    raise ValidationError("This verification code was already used.")
                except:
                    return code
            else:
                raise ValidationError("This verification code has expired.")
        except:
            raise ValidationError("Invalid verification code.")




    verification_code = forms.CharField(max_length=50,
                                        label='',
                                        validators=[is_valid_verification_code]
                                        )

使用丑陋的解决方案进行编辑

我最终得到了下面的代码。我认为这不是正确的方法,但目前我不知道更好,它正在工作

def is_valid_verification_code(code):
    #settings
    time_to_register_in_minutes = 5

    try:
        tmp = SignUpUser.objects.get(signup_verification=code)
        email = tmp.signup_email
        time = tmp.signup_time
        if time >= timezone.now() - datetime.timedelta(minutes=time_to_register_in_minutes):
            try:
                user_already_active = User.objects.get(email=email)
                user_already_active = 1
            except:
                return code
        else:
            try:
                user_already_active = User.objects.get(email=email)
                user_already_active = 1
            except:
                user_already_active = 0
    except:
        raise ValidationError("Invalid verification code.")

    if user_already_active:
        raise ValidationError("This verification code was already used.")
    if not user_already_active:
        raise ValidationError("This verification code has expired.")

您没有按照应有的方式使用 raise。您的代码现在的编写方式,每次成功调用:

check = User.objects.get(email=email)

您将有 100% 的时间引发异常:

raise ValidationError("This verification code was already used.")

你应该把它放在你的 except 块中。

try:
    check = User.objects.get(email=email)
except:
    raise ValidationError("This verification code was already used.")

但是,根据您如何调用名为 get 的方法。您可能需要添加一些逻辑来查看您是否真的需要引发 "already used" 异常。类似于:

if get:
    ValidationError("This verification code was already used.")

How try/except works