Django Ajax Comments

In General Ajax does probably work. It shows in console the message ‘Success’ and the right ‘formData’.
The problem is that the success function parameter ‘response’ takes the wrong data. In console it shows Response: {is_bookmarked : True} from detailFood instead of the comment_data. So how to solve this? Where does the error occur in the view or probably ajax? Or is the success function completely wrong? (Without ajax the comment section works)

def detailFood(request, pk):
    food_country = Country.objects.get(id=pk)

    is_bookmarked = False
    if request.user.is_authenticated:
        bookmark = FoodBookmark.objects.filter(user=request.user).first()
        if bookmark:
            is_bookmarked = bookmark.post.filter(id=pk).exists()
            if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
                response_data = {'is_bookmarked': is_bookmarked}
                return JsonResponse(response_data)   
        
    context = {'food_jobinfo':food_jobinfo,  
                     'user': request.user,
                     'is_bookmarked': is_bookmarked} 
    
    return render(request, 'base/detail/food_detail.html', context)
def addFoodComment(request, pk):
    food_country = Country.objects.get(id=pk)

    if request.method == 'POST':
        if 'comment-form' in request.POST:
            message = FoodMessage.objects.create(
                writer=request.user,
                menu=food_country,
                body=request.POST.get('body')
            )

            if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
                comment_data = serializers.serialize('json', [message])
                response_data = {'comment': comment_data}
                return JsonResponse(response_data)
            else:
                return redirect('detailFood', pk=food_country.id)
        
    return render(request, 'base/comments/food-comments.html', context={})
$(document).ready(function() {
  $('#comment-form').submit(function(event) {
    event.preventDefault(); 

    var form = $(this);
    var url = window.location.href;
    var formData = $('#comment-form').serialize(); 

    console.log('Form data:', formData);  

    $.ajax({
      type: 'POST',
      url: url,
      data: formData,
      headers: { 'X-Requested-With': 'XMLHttpRequest' },
      success: function(response) {
        console.log('Response:', response);

        $('#comment-section').append(response);

        $('.comment-input').val('');

        console.log('Success');
      },
      error: function(xhr, errmsg, err) {
        console.log(err);
      }
    });
  });
});

I’m guessing that you’re loading the page from the detailFood view?

If so, then this:

is going to submit to detailFood.

If you want the AJAX to submit to addFoodComment, then that’s the url you need to use.

I have no way to tell - I’d need to see the template being rendered.

I’m going to guess here that because you’re triggering the event on the button and not on the form, that this is going to be a reference to the button.

Since the button doesn’t have an attribute named action, I’m going to also guess that the url element of the ajax call is going to be undefined.

That’s something that you can verify. You might want to look at the actual request being submitted by the AJAX call - start by checking your server log to see the url being issued.

Also, since you’re wanting to submit this as AJAX and not as POST data, I would recommend not specifying an action on the form, and changing the button type from “submit” to “button”, and then handle the “click” event and not the “submit” event.

1 Like

Hey. I am back. I still have not solved the Ajax django addComment without page refresh. But i think, i found the error (at least i hope).

JavaScript:

So this the first of them console.log(‘FormData:’, formData) displays this in console: FormData: csrfmiddlewaretoken=Txl45Ei9Pw5MU74IYu518IlLvKzyzGHc3S1SsS9muRBzjqD1P94Ojc99q9RAOYqg&body=hello. But then the second in the success function is empty an returns the error message. The other two console.log print normal to the console.

 $('#comment-form').submit(function(event) {
     event.preventDefault();  // Prevent the form from submitting normally

     var form = $(this).closest('form');
     var url = form.attr('action');
     var formData = form.serialize();  // Get the form's action URL

     console.log('FormData:', formData)
     console.log("Before Ajax Request");
     $.ajax({
         type: 'POST',
         url: url,               
         data: formData,
         dataType: 'json',
         success: function(data) {
           console.log('FormData:', data)
             // Append the new comment to the comment section
             if (data.success) {
               // Update the page with the new comment
               var newCommentHtml = '<div class="comment">';
               newCommentHtml += '<p class="comment-writer">' + data.message_body + '</p>';
               newCommentHtml += '<p>By: ' + '@{{' + data.message_writer + '}}' + '</p>';
               newCommentHtml += '</div>';
               $('#comment-section').append(newCommentHtml);

               // Clear the comment form
               $('#comment-form')[0].reset();
             } else {
               alert('Comment could not be added');
             }

             // Clear the comment input field
             $('.comment-input').val('');

         },
         error: function(xhr, errmsg, err) {
             console.log(err);
         }
     });
     console.log("After Ajax Request");
 }); 

views.py 

def addFoodComment(request, pk):
   food_country = Country.objects.get(id=pk)
   print("addFoodComment")                    # This prints to terminal  
   
   if request.method == 'POST':
       print("create Message")                             # This prints to terminal  
       if 'comment-form' in request.POST:
           message = FoodMessage.objects.create(
               writer=request.user,
               menu=food_country,
               body=request.POST.get('body')
           )
          
          print("before JsonResponse")                 # This does not print to terminal
          response_data = {
               'success': True,
               'message_id': message.id,
               'message_body': message.body,
               'message_writer': message.writer.username,
           }
           print(response_data)                           # This does not print to terminal
           return(response_data)

        elif 'reply-form' in request.POST:   .... 
       
   return render(request, 'base/comments/food-comments.html', context={})   

Any ideas what could be the problem why it does not print to terminal? This is probably also the problem why it does not work?

comment-form is not in form data (which is expected as this is the id of the form and not thename of a forms field). Hence, the test if ‘comment-form’ in request.POST` cannot be satisfied.

You should change the test to check for presence of 'body' instead.

1 Like