Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax, Django: status 200 but throws error instead of success

I am trying to post comment with ajax, but it is not working. When I press button console is not printing any error (like 404 etc.), comment is not being posted. Object returned by error:

{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …} abort: ƒ (e) always: ƒ () catch: ƒ (e) done: ƒ () fail: ƒ () getAllResponseHeaders: ƒ () getResponseHeader: ƒ (e) overrideMimeType: ƒ (e) pipe: ƒ () progress: ƒ () promise: ƒ (e) readyState: 4 responseText: "↵" setRequestHeader: ƒ (e,t) state: ƒ () status: 200 statusCode: ƒ (e) statusText: "OK" then: ƒ (t,n,r) proto: Object

In command line I see:

"POST / HTTP/1.1" 200 5572

When I change button to "submit" it is posting and responding with proper JSON like:

{"comment": {"id": 16, "author": 1, "content": "test", "post": 12}}

My code is below, any help is appreciated:

views.py

def homepage(request):
    profiles = Follow.objects.filter(follow_by=request.user.profile).values_list('follow_to', flat=True)
    posts = Post.objects.filter(author_id__in=profiles).order_by('-date_of_create')
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            pk = request.POST.get('pk')
            post = Post.objects.get(pk=pk)
            new_comment = Comment.objects.create(
                author = request.user.profile,
                post = post,
                content = form.cleaned_data['content']
            )
            return JsonResponse({'comment': model_to_dict(new_comment)}, status=200)
    form = CommentForm()
    context = {
        'posts': posts,
        'form': form
    }
    return render(request, 'posts/homepage.html', context=context)

template

<div class="comments" id="{{ post.pk }}" style="display: none">
            {% include 'posts/comments.html' %}
            <form action="" method="post" class="commentForm" data-url="{% url 'post_comments' post.pk %}">
                {% csrf_token %}
                <input type="hidden" name="pk" value="{{ post.pk }}">
                {{ form.as_p }}
                <button type="button" class="commentBtn" id="{{ post.pk }}">Comment</button>
            </form>

addComment.js

$(document).ready(function () {
    $('.commentBtn').click(function () {
        let serializedData = $('.commentForm').serialize();
        let btn = $(this);
        let id = btn.attr('id');
        console.log($(".commentForm").data('url'));
        $.ajax({
            url: $(".commentForm").data('url'),
            data: serializedData,
            type: 'post',
            dataType: 'json',
            success: function (data) {
                console.log(data);
                $(`#${id}.comments`).load('/posts/comments/' + data.post);
                $('textarea').val('');
            },
            error: function(textStatus) {
                console.log(textStatus)
            }
        })
    })
})

Edit: I used this question: Ajax request returns 200 OK, but an error event is fired instead of success , deleted dataType: 'json' and added contentType: 'application/json' and now I got 403 error.

like image 497
bkrop Avatar asked Oct 26 '20 17:10

bkrop


1 Answers

As you have use $('.commentForm') to send data of form to backend it will get all forms with class commentForm and send data of all forms that's the reason its not working .Instead you can change this $('.commentForm').serialize() to $(this).closest(".commentForm").serialize().

Also , you are using #${id}.comments inside success function of ajax this will override any content inside #${id}.comments and load new content from url i.e : /posts/comments/.. .So , to avoid this one way would be surround your {% include 'posts/comments.html' %} with some outer div and then change your selector i.e : #${id}.comments > .yourouterdivclassname so new content will be loaded inside that div only thus form will not get removed .

like image 185
Swati Avatar answered Nov 11 '22 06:11

Swati