Juan Sebastian Eljach
Juan Sebastian Eljach

Reputation: 11

Django + Ajax error in returning data

I have a model called Item and I'm trying to create Items with Ajax, everything looks to be working ok, but I'm getting and error at the end of the process, in the success function in Ajax. I have been reading a lot of answers to questions like this here in StackOverflow but I couldnt make it work:

This is my model:

PRIORITY_CHOICES = (
(1, 'Low'),
(2, 'Normal'),
(3, 'High'),
)

class Item(models.Model):
name = models.CharField(max_length=60)
description = models.TextField(max_length=1000)
created = models.DateTimeField(auto_now_add=True)
priority = models.IntegerField(choices=PRIORITY_CHOICES, default=1)
done = models.BooleanField(default=False)
meeting = models.ForeignKey(Meeting)

def __str__(self):
    return self.name

This is my view, whichs is working Ok and saving the data into de database:

from .forms import AddItemForm
from .utils import render_to_json_response

class AjaxFormResponseMixin(object):
    def form_invalid(self, form):
        return render_to_json_response(form.errors, status=400)

    def form_valid(self, form):

        # save
        self.object = form.save()

        # initialize an empty context
        context = {}

        # return the context as json
        return render_to_json_response(self.get_context_data(context))

class AjaxItemCreateView(AjaxFormResponseMixin, CreateView):
    form_class = AddItemForm

    def get_context_data(self, context):
        context['success'] = True
        context['name'] = self.object.name
        context['description'] = self.object.description
        return context

as you can see, I'm using a custom shortcut called render_to_json_response in order to parse data in Json

this is the code of the shortcut (Please notice that I'm printing the context, in order to verify the data):

from django.http import JsonResponse

def render_to_json_response(context, **response_kwargs):
    print (context)
    return JsonResponse(context)

(if you're wondering why I'm using this simple shortcut it's because previously I was trying to return the response with HttpResponse and specifying content_type="application/json", but it also wasn't working)

This is my ajax code:

function AddItem(event){
var csrftoken = getCookie('csrftoken');
var item_name = $('#item-name').val();
var item_desription = $('#item-description').val();
var item_priority = $('#item-priority').val();
var item_meeting_pk = $('#item-meeting-pk').val();
var url = "/item/add/";
$.ajax({
   type: "POST",
   url: url,
   data: {
       'name': item_name,
       'description': item_desription,
       'priority': item_priority,
       'meeting': item_meeting_pk ,
       'csrfmiddlewaretoken': csrftoken
   },
   success: function(data){
    alert("success");
    alert(data);
   },
   complete: function(data){
    alert("completed");
    alert(JSON.stringify(data));
   }
});
}

and, finally, this is the form that calls the AddItem() function:

<form>
   {% csrf_token %}
     <input type="text" placeholder="Nombre del item" id='item-name'/>
     <input type="text" placeholder="Descripción del item" id='item-description'/>
     <select id="item-priority" name="provider" class="form-control">
        <option value="1">Baja</option>
        <option value="2">Normal</option>
        <option value="3">Alta</option>
     </select>
     <input type='hidden' id='item-meeting-pk' value='{{ meeting.pk }}'>
     <button onclick='AddItem()' class="button-blue" >Agregar</button>
     </form>

When I submit the form, everything goes fine, and in my django shell I can see that the post request is returning 200 and the data is printing ok:

{'name': 'asdkkasd', 'description': 'sdksdksjd', 'success': True}
[29/Aug/2015 08:34:22]"POST /item/add/ HTTP/1.1" 200 65

in the ajax function I have javascript alerts in both success and complete, but only the complete's one is executing and this is what I'm getting with the execution of alert(JSON.stringify(data));:

{"readyState": 0, "responseText":"", "status":0, "statusText": "error"}

I hope you can help me, thank you :)

Upvotes: 0

Views: 1790

Answers (2)

Daniel Roseman
Daniel Roseman

Reputation: 599470

Your form is almost certainly invalid; you're returning a 400 status in that case from form_invalid, which triggers jQuery to call the failure function if there is one, rather than success.

Unfortunately, you can't use proper RESTful status codes in this kind of situation. An invalid form submission should still return a 200.

Upvotes: 1

cafebabe1991
cafebabe1991

Reputation: 5176

There is a difference between success and complete function of the ajax function that you are using...

success

It gets called on a response of 200 (OK).

complete

This will get called always , well as the name suggests the request did succeed, even if was a failure on the server side or OK response. It just succeeded (ie: landed your server and brought something back to offer to your client(browser,mobile whatever).So that's complete method for.

You can do away with this method and can use only success if not needed otherwise.

For more info. Read here

FYI :

The readystate output you showed says 0 , hence the request isn't initialized.It should be 4 for the request to be complete.

Upvotes: 0

Related Questions