Question

I have a class based view that displays a page and handles POST requests, like so:

 class citywall (View):


        def get(self, request, *args, **kwargs):
            template_name = 'citywall.html'
            city_slug = kwargs['city_slug']
            context = self.get_context_data(city_slug)
            return render_to_response(template_name, context, RequestContext(request))



        def post(self, request, *args, **kwargs):       



            if request.is_ajax:                        
                if request.POST.has_key('comment'):
                        #process comment
                        ...
                if request.POST.has_key('vote'):
                        #process vote

                      ...

The problem is when I try to POST the form with AJAX, two requests are being sent. The Ajax request and then a regular POST request.

This is my comment form in html:

<form class="comment_form" data-id="{{post.id}}" method="POST" >{% csrf_token %}
   <textarea  rows = "1"  name="comment" class="form-control" placeholder="Write a comment..." ></textarea>
   <button type="submit" class="btn btn-info">Go!</button>
</form>

This is the jQuery code:

var comment_form = $('.comment_form')
   comment_form.submit(function(){

   var post_id = $(this).data('id');
   var comment = $(this).find('textarea[name="comment"]').val();
   $.ajax({
            url: "",
            dataType:"json",
            type:"POST",
            data:{

              comment: comment,
              post_id: post_id,
              csrfmiddlewaretoken:'{{csrf_token}}',
            },
            success:function(json)
            {

               alert(json);


            },

        });     
 }); 

When I submit the form this is happening:

  1. AJAX POST is made with its json data(post_id, comment, csrf).

  2. Response for the AJAX post is received back in browser.

  3. POST is made with html form data(comment and csrf).

why is a second POST being made?

I have several types of forms on the page for example. comment form, voting form, etc and I want to make all of them AJAX. Is it a good idea to implement all of them with the above mentioned method?

Était-ce utile?

La solution

The second POST with your form data is sent because your submit event handler doesn't return False. If you want to prevent the form from submitting when clicking the submit button, you have to return False in the event handler. The event handler can also be told to prevent form submission by calling e.preventDefault() on the event object that is being passed to the submit handler.

The reason for this behaviour is that, by default, the event fired when a submit button is clicked submits the forms at the very end of the event handling chain. So what happens is that in your event handler you are send a AJAX POST call (which is asynchronous), and the very next moment the handler returns without prevent the event from form submission. This results in both AJAX and form being sent.

e.preventDefault() tells the event e to avoid doing the default action specific to this event, in this case form submission. With this added, when $.ajax finishes and all the handlers are done handling the event the default handler is checked if it's allowed to be run. Since you have prevented it, nothing happens.

The very same method can be used to, e.g. prevent the webpage following a link <a> when clicked.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top