当用户在加载到新页面之前点击提交按钮多次,可以防止多次提交 [英] prevent multiple submissions when user clicks submit button multiple times before loading to the new page
问题描述
我的html
< form id =post_formmethod =postaction =/ add_post / ENCTYPE = 多部分/格式数据 >
{%csrf_token%}
{{form | crispy}}
< input type =submitname =submitvalue =submit>
< / form>
我的views.py
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name ='main / add_post.html'
def form_valid(self,form):
self.object = form.save(commit = False)
#任何手动设置到这里
#self .object.category = Category.objects.filter(category__in = categories).all()
self.object.moderator = self.request.user
self.object.image = extract self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post',args = [self.object.slug])
@method_decorator(login_required)
def dispatch(self,request,* args,** kwargs):
return super(PostCreateView,自我).dispatch(request,* args,** kwargs)
编辑:我c挂起它喜欢这样
{%block content%}
< div class =col-sm-5 >
< form id =post_formmethod =postaction =/ add_post /enctype =multipart / form-data>
{%csrf_token%}
{{form | crispy}}
< input type =submitid =buttonname =submitvalue =올리기>
< / form>
< / div>
< div class =col-sm-4style =width:400px; height:250px; border:1px solid black;>
< h3>规则< / h3>
< / div>
< div class =col-sm-3style =width:420px; height:750px; border:1px solid black; >
< h3> ad< / h3>
< / div>
{%endblock%}
< script>
jQuery('input [name = submit]')。on('click',function(){
if(jQuery(this).hasClass('active')){
return false;
}
else {
jQuery(this).addClass('active');
}
});
< / script>
{%include'footer.html'%}
最终编辑:希望这是正确的?任何建议?
import datetime
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name ='main / add_post.html'
def form_valid(self,form):
self。对象= form.save(commit = False)
#任何手动设置到这里
#self.object.category = Category.objects.filter(category__in = categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self。 object.content)
self.object.save()
如果没有hasattr(self.request.session ['last_submitted']):
self.request.session [' last_submitted'] = datetime.datetime.now()
return HttpResponseRedirect(reverse('post',args = [self.object.slug]))
else:
delta = datetime.datetime .now() - s elf.request.session ['last_submitted']
如果delta.seconds< 60:#假设允许在60秒后重新提交
返回http.HttpForbidden()#or一些其他更好的消息?
else:
return HttpResponseRedirect(reverse('post',args = [self.object.slug]))
@method_decorator(login_required)
def dispatch self,request,* args,** kwargs):
return super(PostCreateView,self).dispatch(request,* args,** kwargs)
使用提供的解决方案编辑
class PostCreateView(CreateView):
model =发布
form_class = PostForm
template_name ='main / add_post.html'
def form_valid(self,form):
如果不是hasattr(self.request.session ['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session ['last_submitted '] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session ['last_submitted'])
delta = datetime.datetime .now() - last_submitted
save_it =(delta.seconds> 60)#假设允许在60秒后重新提交
如果save_it:
self.object = form.save(commit = False)
#任何手动设置到这里
#self.object.category = Category.objects.filter(category__in = categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(反向('post',args = [self.object.slug])
else:
#像往常一样考虑重定向,如果用户只是错误地点击了两次
return self.form_invalid形式)#或Http错误代码
如果这是buttton:
< input type =submitname =submitvalue =submitid =preventDouble> ;
使用jQuery:
$(#preventDouble)。on(submit,function(){
$(this).unbind(submit);
$(this) (submit,function(){return false;});
};
第一次提交后,jQuery会附加一个将取消进一步提交的事件。
请注意,此事件不会检查表单是否实际成功地被提交到服务器。 / p>
这可能会回答您的问题,但是在服务器上跟踪多次提交更安全,更好的方法,例如在会话中添加last_submitted属性,并防止进一步提交如果datetime.datetime.now距离session.last_submitted不到1分钟:
import datetime
import pickle
def form_valid(self,form):
如果没有hasattr(self.request.session ['last_submitted']):
last_submitted = pickle.dumps(datetime。 datetime.now())
self.request.session ['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session ['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it =(delta.seconds> 60):#假设允许在60秒后重新提交
如果save_it:
self.object = form.save(commit = False)
#任何手动设置到这里
#self.object.category = Category.objects.filter(category__in = categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect (reverse('post',args = [self.object.slug]))
else:
#像往常一样考虑重定向,如果用户只是错误地点击了两次
return self.form_invalid (形式)#或Http错误代码
编辑
import datetime
import pickle
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name ='main / add_post.html'
def form_valid(self,form):
如果不是hasattr(self.request.session ['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session ['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session ['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it =(delta.seconds> 60)#假设允许在60秒后重新提交
如果save_it:
self.object = form.save(commit = False)
#任何手动设置到这里
#self.object.category = Category.objects.filter(category__in = categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(反向('post',args = [self.object.slug])
else:
#像往常一样考虑重定向,如果用户只是错误地点击了两次
return self.form_invalid表单)#或Http错误代码
I have googled around and it seems like there are many possibilities for php. But I haven't found anything good solution for django. I saw some people using client side javascript code for this, but I just don't get how to fix this. Problem I;m having is:when user writes a post, and click submit button fast twice before new page gets loaded then two posts will be made. Here's my code, thanks in advance. my html
<form id="post_form" method="post" action="/add_post/" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" name="submit" value="submit">
</form>
my views.py
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self, form):
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(PostCreateView, self).dispatch(request, *args, **kwargs)
Edit: I changed it to like this
{% block content %}
<div class="col-sm-5">
<form id="post_form" method="post" action="/add_post/" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" id="button" name="submit" value="올리기">
</form>
</div>
<div class="col-sm-4" style="width:400px; height:250px; border:1px solid black;">
<h3>rule</h3>
</div>
<div class="col-sm-3" style="width:420px; height:750px; border:1px solid black;" >
<h3>ad</h3>
</div>
{% endblock %}
<script>
jQuery('input[name=submit]').on('click', function(){
if(jQuery(this).hasClass('active')){
return false;
}
else{
jQuery(this).addClass('active');
}
});
</script>
{% include 'footer.html' %}
Final Edit: hope this is right? any suggestion?
import datetime
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self, form):
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
if not hasattr(self.request.session['last_submitted']):
self.request.session['last_submitted'] = datetime.datetime.now()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
delta = datetime.datetime.now() - self.request.session['last_submitted']
if delta.seconds < 60: # assume allow re-submit after 60 seconds
return http.HttpForbidden() #or some other better message??
else:
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(PostCreateView, self).dispatch(request, *args, **kwargs)
Edit with the solution provided
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self,form):
if not hasattr(self.request.session['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it = (delta.seconds > 60) # assume allow re-submit after 60 seconds
if save_it:
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
# consider redirect as usual, if the user just clicked twice by mistake
return self.form_invalid(form) # or Http error code
If this is the buttton:
<input type="submit" name="submit" value="submit" id="preventDouble">
With jQuery:
$("#preventDouble").on("submit",function(){
$(this).unbind("submit");
$(this).on("submit",function(){return false;});
};
After the first submit, jQuery will attach an event that will cancel further submits.
Note that this event does not check if the form was actually successfully submited to the server.
This may answer your question, but it's a safer and better approach to track multiple submits on the server, e.g. adding a "last_submitted" attribute to the session, and prevent further submits if datetime.datetime.now is less than 1 minute from session.last_submitted:
import datetime
import pickle
def form_valid(self,form):
if not hasattr(self.request.session['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it = (delta.seconds > 60): # assume allow re-submit after 60 seconds
if save_it:
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
# consider redirect as usual, if the user just clicked twice by mistake
return self.form_invalid(form) # or Http error code
Edit
import datetime
import pickle
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self,form):
if not hasattr(self.request.session['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it = (delta.seconds > 60) # assume allow re-submit after 60 seconds
if save_it:
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
# consider redirect as usual, if the user just clicked twice by mistake
return self.form_invalid(form) # or Http error code
这篇关于当用户在加载到新页面之前点击提交按钮多次,可以防止多次提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!