【分享】利用decorator实现Django表单防重复提交
2010-12-25 01:14 码农.KEN 阅读(3373) 评论(1) 编辑 收藏 举报背景:
解决思路:
实现:
为了方便使用,我们将上述思路写成一个decorator(装饰器). 当然也是为了符合DRY嘛;代码很简单就看中间那几行,需注意唯一的一个参数page_key,为了不跟多个表单页面发生Session key冲突。(补充一点:必须将表单填写页面的view同时使用@never_cache装饰,因为django默认将所有view都做缓存,当再次进入表单页时,就不会重新生成随机串,导致校验无故失败。。。)
# coding:utf-8 try: from functools import wraps except ImportError: from django.utils.functional import wraps # Python 2.4 fallback. import random from django.conf import settings from django.utils.decorators import available_attrs from django.utils.hashcompat import md5_constructor if hasattr(random, 'SystemRandom'): randrange = random.SystemRandom().randrange else: randrange = random.randrange _MAX_CSRF_KEY = 18446744073709551616L # 2 << 63 def _get_new_submit_key(): return md5_constructor("%s%s" % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest() def anti_resubmit(page_key=''): def decorator(view_func): @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): if request.method == 'GET': request.session['%s_submit' % page_key] = _get_new_submit_key() print 'session:' + request.session.get('%s_submit' % page_key) elif request.method == 'POST': old_key = request.session.get('%s_submit' % page_key, '') if old_key == '': from django.http import HttpResponseRedirect return HttpResponseRedirect('/page_expir') request.session['%s_submit' % page_key] = '' return view_func(request, *args, **kwargs) return _wrapped_view return decorator
使用示例:
1 @anti_resubmit(page_key='your_view')
2 def your_view(request):
3 '''若是表单填写页和POST的view不是同一个,則需在两个view上都使用anti_resubmit装饰器'''
4 pass #您可别跟着pass噢
2 def your_view(request):
3 '''若是表单填写页和POST的view不是同一个,則需在两个view上都使用anti_resubmit装饰器'''
4 pass #您可别跟着pass噢
本博客所有原创内容均可随意转载,但请注明来源!