是否存在防止Django表单重复提交的库?
我想找个办法来防止用户重复提交我的表单。我已经用JavaScript禁用了提交按钮,但还是有少数用户能找到方法重复提交。
我想创建一个可以重复使用的库来解决这个问题。
在我理想中的这个库里,代码块看起来大概是这样的:
try:
with acquire_lock({'field1':'abc', 'field2':'def'}) as lock:
response = #do some credit card processing
lock.response = response
except SubmissionWasDuplicate, e:
response = e.response
这个锁表大概是这样的:
duplicate_submission_locks
- submission_hash # 提交参数的MD5值
- response # 序列化的数据
- created_at # 用于清理这个表
- lock_expired # 一个布尔值,表示锁是否过期
有没有人知道这个东西是否已经存在?看起来写起来并不难,如果没有的话,我可能会自己写一个。
5 个回答
3
老实说,最简单也最好的做法就是用 HTTPRedirect() 方法跳转到感谢页面。如果感谢页面和表单是同一个页面,那也没问题,你照样可以这样做。
12
你可以用一个会话来存储哈希值。
import hashlib
def contact(request):
if request.method == 'POST':
form = MyForm(request.POST)
#join all the fields in one string
hashstring=hashlib.sha1(fieldsstring)
if request.session.get('sesionform')!=hashstring:
if form.is_valid() :
request.session['sesionform'] = hashstring
#do some stuff...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else
raise SubmissionWasDuplicate("duplicate")
else:
form = MyForm()
用这种方法(不删除会话的cookie),用户在会话过期之前无法重新存储数据。顺便说一下,我假设有某种方式可以识别发送数据的用户。
6
解决这个问题的一个简单方法是给每个表单添加一个独特的哈希值。这样,你就可以有一个当前表单的滚动列表。当一个表单被提交,或者哈希值过期时,你可以把它从列表中移除,并拒绝任何没有匹配哈希值的表单。
使用HTTP重定向是正确的做法,正如之前提到的那样。
不幸的是,连Django自带的管理后台也会遇到与这个问题相关的麻烦。在某些情况下,跨站脚本的框架可以帮助防止一些问题,但我担心目前的生产版本并没有内置这个功能。