简体   繁体   中英

Django form field instance variable

In order to make a simple captacha-like field, I tried the following:

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

Every time my answer is wrong, the label is changed as expected but the test is performed against the first values of int_1 and int_2 and not against the newly randomly generated values. I don't understand how Field object are created and why I can't access the values of my field.

Thanks in advance

Have a think about how this works in your view. When you render the form, the field is instantiated and sets the label to your random values, which is fine. Now, the user posts back to the view: what happens? Well, the form is instantiated again, as is the field, and the field is set to two new random values. Not surprisingly, this won't match up to the previous value, because you haven't stored that anywhere.

To do anything like this, you need to store state somewhere so it is preserved between requests. You could try putting it in the session, perhaps: or, a better way might be to hash the two values together and put them in a hidden field, then on submit hash the submitted value and compare it against the one in the hidden field. This would probably need to managed at the form level, not the field.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM