当用户在加载到新页面之前多次单击“提交”按钮时,防止多次提交

prevent multiple submissions when user clicks submit button multiple times before loading to the new page

本文关键字:提交 按钮 用户 单击 新页面 加载      更新时间:2023-09-26

我用谷歌搜索过,似乎php有很多可能性。但是我还没有为django找到任何好的解决方案。我看到有些人为此使用客户端 javascript 代码,但我只是不知道如何解决这个问题。我遇到的问题是:当用户写一篇文章时,在新页面加载之前快速单击提交按钮两次,然后制作两个帖子。这是我的代码,提前感谢。我的网页

<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>

我的 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)       

编辑:我把它改成这样

{% 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' %}

最终编辑:希望这是对的?有什么建议吗?

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) 

使用提供的解决方案进行编辑

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

如果这是屁股:

<input type="submit" name="submit" value="submit" id="preventDouble">

使用 jQuery:

$("#preventDouble").on("submit",function(){
    $(this).unbind("submit");
    $(this).on("submit",function(){return false;});
};

第一次提交后,jQuery将附加一个事件,该事件将取消进一步的提交。

请注意,此事件不会检查表单是否确实已成功提交到服务器。

这可能会回答您的问题,但这是跟踪服务器上多个提交更安全、更好的方法,例如,向会话添加"last_submitted"属性,并在 datetime.datetime.now 距离session.last_submitted不到 1 分钟时防止进一步提交:

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      

编辑

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

不确定您的项目是否使用 jquery lib。 如果确实尝试以下操作:

jQuery('input[name=submit]').on('click', function(){
 if(jQuery(this).hasClass('active')){
   return false;
 }
 else{
  jQuery(this).addClass('active');
 }
});

这将检查按钮是否已被单击。如果是这样,它将不会重新提交页面。如果您不使用任何客户端库,那么我可以将其更改为本机 js。