0

为了制作一个简单的类似验证码的字段,我尝试了以下方法:

class CaptchaField(IntegerField):
    def __init__(self, *args, **kwargs):
        super(CaptchaField, self).__init__(*args, **kwargs)
        self.reset()

    def reset(self):
        self.int_1 = random.randint(1, 10)
        self.int_2 = random.randint(1, 10)
        self.label = '{0} + {1}'.format(self.int_1, self.int_2)

    def clean(self, value):
        value = super(CaptchaField, self).clean(value)
        if value != self.int_1 + self.int_2:
            self.reset()
            raise ValidationError(_("Enter the result"), code='captcha_fail')
        return True

每次我的回答错误时,标签都会按预期更改,但测试是针对 int_1 和 int_2 的第一个值执行的,而不是针对新随机生成的值。我不明白 Field 对象是如何创建的,以及为什么我无法访问我的字段的值。

提前致谢

4

1 回答 1

2

考虑一下您认为这是如何工作的。当您呈现表单时,该字段被实例化并将标签设置为您的随机值,这很好。现在,用户发回视图:会发生什么?好吧,表单被再次实例化,字段也是如此,并且该字段被设置为两个新的随机值。毫不奇怪,这与之前的值不匹配,因为您没有将它存储在任何地方。

要执行此类操作,您需要将状态存储在某处,以便在请求之间保留它。您可以尝试将其放入会话中,也许:或者,更好的方法可能是将两个值散列在一起并将它们放在隐藏字段中,然后提交散列提交的值并将其与隐藏字段中的值进行比较。这可能需要在表单级别进行管理,而不是字段。

于 2013-10-03T11:04:51.943 回答