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

时间:2016-02-11 05:38:13

标签: javascript python django

我已经google了一下,似乎有很多可能性的PHP。但我还没有为django找到任何好的解决方案。我看到有些人使用客户端javascript代码,但我不知道如何解决这个问题。我遇到的问题是:当用户写一篇文章,然后在新页面加载之前快速点击提交按钮两次,那么将发布两个帖子。这是我的代码,提前谢谢。 我的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)       

编辑:我把它改成了这个

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

2 个答案:

答案 0 :(得分:1)

如果这是按钮:

<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

答案 1 :(得分:0)

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

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

这将做的是检查是否已经点击了按钮。如果确实如此,则不会重新提交页面。 如果您没有使用任何客户端库,那么我可以将其更改为Native js。