user1871528
user1871528

Reputation: 1775

AJAX and DJANGO form

I'm a newbie to both Ajax and Django. To simplify the question assume I have one hidden form and two objects, and I ask the users to click some of the position of the objects. Each clicks fills out a part of the form. I want the form to be filled out once for each object. so twice overall. When the form is filled for the first subject I want to send the form via Ajax to the server, without refreshing the page, and allow the form to be refilled for the second object. However, for some reason I can't get the form to be send via ajax.

here is my code: index.html:

<html>
<body>
<script src="{{ STATIC_URL }}prototype.js"></script>
<script src="{{ STATIC_URL }}jquery.js"></script>
<script>

  objectID= 1;
  num_obj = {{num_obj}}

  function ajax_post(){
    $('#inputform').submit(function() {  
        $.ajax({ 
            type: 'POST',
            url: '/index/',
            data: $(this).serialize(),
            success: function(data){alert(data)}

         }); // end new Ajax.Request
    });
  }


 function onDocumentMouseDown( event ) {
        ....do stuff
        if (objectID < num_obj){
           ajax_post()
           }
        if (objectID == num_obj){ 
            $("form").submit();}
        objectID ++;
        $("form").clearForm();
        document.forms[0].ObjectID.value = objectID;
        }
  </script>
  <form action="" method="post" id="inputform">
      <div id="ajaxwrapper">
       {% csrf_token %}
       <table>
        {{ form.as_table }}
       </table>
     </div>
  </form>
</body>
</html>

my view.py:

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import *
from firstapp.forms import PracForm3

num_obj=2

def index(request):
   Obj.objects.all().delete()
   if request.method == 'POST':
    form = PracForm3(request.POST)
    print "\n\n\n\n\n"
    if request.is_ajax():
      print "yaaaaay AJAX"
      print request.POST
    else:
      print "noooooo"
    print "\n\n\n\n\n"
    if form.is_valid():
      cd = form.cleaned_data
      .....
      if cd['ObjectID'] == num_obj:
        return HttpResponseRedirect('/submit')
   else:
     form = PracForm3()
     dic = {'form': form, 'num_obj': num_obj, ...}
   return render_to_response('index.html', dic, context_instance=RequestContext(request))  

my urls.py:

from django.conf.urls import patterns, include, url
from firstapp.views import index, submit
from django.conf import settings

urlpatterns = patterns('',
('^index$', index),
('^submit$', submit),
)

for some reason, my Ajax does not work anyone knows what I'm doing wrong?

Upvotes: 6

Views: 2294

Answers (5)

esse
esse

Reputation: 5549

This is probably related CSRF for AJAX posts, you have to remember to pass the CSRF token in as POST data with every POST request. You may need to add this code here, which are the Django docs that talk about Django+CSRF+AJAX.

I notice in your Django view that you are redirecting to "submit" Typically with ajax I would not redirect to a different url, I would use a HttpResponse and return some string value, such as JSON. I also don't know why you have print statements in your view, unless you are steeping into that view in a debugger. For testing/debugging you should have a variable that you assign some string to, and then pass that back to your ajax. Then in your ajax you can read the message from the view, something like this.

def index(request):
    ...
    if request.is_ajax():
        msg = 'it worked'
    else:
        msg = 'i am sad'
    return HttpResponse(msg)
    ...

Also you javascript should have a success and error function in the ajax call, you only have success so you are not catching errors, given the view tad bit your javascript would look like this:

...
success: function(data){alert(data)}, 

error: function(data){alert(data)}
...         

It looks like you may have several issues going on. If you have not done the CSRF stuff that I gave you the link to that is an issue too, for testing use the csrf_exempt if you don't want to address doing it the preferred way. Try the code bits above and see if that makes progress for you.

Upvotes: 3

Will Farley
Will Farley

Reputation: 680

The csrf token is included in $('#input-form') post request, so I don't think that was the issue. I think the problem is that you aren't converting the context into json in your view. This is from the docs example:

import json
from django.http import HttpResponse

class JSONResponseMixin(object):
    """
    A mixin that can be used to render a JSON response.
    """
    response_class = HttpResponse

    def render_to_response(self, context, **response_kwargs):
        """
        Returns a JSON response, transforming 'context' to make the payload.
        """
        response_kwargs['content_type'] = 'application/json'
        return self.response_class(
            self.convert_context_to_json(context),
            **response_kwargs
        )

    def convert_context_to_json(self, context):
        "Convert the context dictionary into a JSON object"
        # Note: This is *EXTREMELY* naive; in reality, you'll need
        # to do much more complex handling to ensure that arbitrary
        # objects -- such as Django model instances or querysets
        # -- can be serialized as JSON.
        return json.dumps(context)

Upvotes: 1

user1871528
user1871528

Reputation: 1775

I commented out the CSRF so it wasn't that my ajax function was the problem. Here is the correct way:

function ajax_post(){ 
    $.ajax({ 
        type: 'POST',
        url: '/index/',
        data: $(this).serialize(),
        success: function(data){alert(data)}

     }); // end new Ajax.Request
}

thanks for all your input

Upvotes: 0

Yaguang
Yaguang

Reputation: 702

It may caused by the csrf, add @csrf_exempt before the method name will be helpful.

@csrf_exempt
def method(args):
    pass

Upvotes: 0

Jesse the Game
Jesse the Game

Reputation: 2630

You're requesting /index/ in your ajax call, but your pattern matches /index.

Upvotes: 0

Related Questions