当用户在加载到新页面之前点击提交按钮多次,可以防止多次提交 [英] prevent multiple submissions when user clicks submit button multiple times before loading to the new page

查看:110
本文介绍了当用户在加载到新页面之前点击提交按钮多次,可以防止多次提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经google了,似乎有很多php的可能性。但我没有找到任何好的解决方案django。我看到有些人使用客户端JavaScript代码,但我只是不知道如何解决这个问题。问题我有:当用户写一个帖子,并在新页面加载之前点击提交按钮快两次,然后两个帖子将被创建。这是我的代码,谢谢提前。
我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆