如何构建一个需要延迟重新提交的Django表单?

时间:2010-05-06 20:08:19

标签: python django forms django-forms timestamp

为了避免垃圾邮件,我想添加一个等待时间来重新提交表单(即用户应该等待几秒钟提交表单,除了第一次提交此表单< /强>)。

为此,我在表单中添加了一个timestamp(以及一个包含时间戳加security_hash的{​​{1}}字段,以确保时间戳不会被填充。这看起来像:

settings.SECRET_KEY

这很好用。但是仍然存在一个问题:用户首次提交表单时会检查时间戳,我需要避免使用

有什么想法来解决它吗?

谢谢! : - )

2 个答案:

答案 0 :(得分:2)

  

用户第一次提交表单时会检查时间戳,我需要避免这种情况。

如果这是问题,您是否无法创建设置时间戳-5分钟的表单?

答案 1 :(得分:2)

执行此操作的一种方法是将initial值设置为time,假设为0,并在表单验证后将其更新为当前时间戳,并仅在不为0时检查时间戳:

class MyForm(forms.Form):
    timestamp     = forms.IntegerField(widget=forms.HiddenInput, initial=0)
    #look at the initial = 0

    security_hash = forms.CharField(min_length=40, max_length=40, widget=forms.HiddenInput)


    def clean_timestamp(self):
        """Make sure the delay is over (5 seconds)."""
        ts = self.cleaned_data["timestamp"]
        if timestamp != 0 and not time.time() - ts > 5:
            raise forms.ValidationError("Timestamp check failed")
        return ts

    def clean(self):
        cleaned_data = self.cleaned_data
        if len(self._errors) == 0: #it validates
            cleaned_data["timestamp"] = time.time()
        return cleaned_data

另一种可能的解决方案是使用sessions。它更安全但不防弹。使用之前的apporach,用户可以多次发送相同的发布数据,并且表单将多次验证(因为他发送的是相同的时间戳)。使用会话时,您需要用户启用Cookie,但他们将无法发送验证时间超过5秒的帖子数据。

这样一旦正确的表单提交发生,您可以将时间保存在用户的会话密钥中,并在重新验证表单之前进行检查。这在视图中很容易完成。如果要在表单逻辑级别执行此操作,则需要在接收请求的表单中创建自己的clean方法(以便可以使用会话)。请注意,用户可以清理他的cookie并以“新”用户身份发布。

希望这有帮助。