Ajax,Django:状态码200但抛出错误而不是成功

8

我正在尝试使用ajax发布评论,但是没有起作用。当我按下按钮时,控制台没有打印任何错误(如404等),评论也没有被发布。

返回的错误对象:

{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

在命令行中,我看到:

"POST / HTTP/1.1" 200 5572

当我将按钮更改为“提交”时,它会发布并响应适当的JSON,如下所示:

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

以下是我的代码,请帮忙解决:

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)

模板

<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)
            }
        })
    })
})

编辑: 我使用了这个问题:Ajax请求返回200 OK,但触发错误事件而不是成功,删除了dataType: 'json'并添加了contentType: 'application/json',现在出现403错误。


你好,$("commentForm").data('url').. 附近缺少了一个 . - Swati
嗨,谢谢,但是它没有帮助。 - bkrop
2
另外,做一件事情$('.commentForm').serialize()打印出来看看它给了什么。我可以看到在你的代码中有多个帖子,每个帖子都会有评论部分...所以这将从所有类为commentForm的表单发送数据。相反,将其更改为$(this).closest(".commentForm").serialize(),这样只会从单击按钮的表单获取数据。 - Swati
1
那就是问题所在。非常感谢。将其发布为答案以获得额外的奖励;)。附注:如何在发布评论后使表单不消失? - bkrop
1个回答

4

由于您使用了$('.commentForm')向后端发送表单数据,它将获取所有具有class为commentForm的表单,并发送所有表单的数据,这就是它不起作用的原因。相反,您可以将此$('.commentForm').serialize()更改为$(this).closest(".commentForm").serialize()

另外,您在ajax的success函数中使用了#${id}.comments,这将覆盖#${id}.comments内的任何内容,并从url即/posts/comments/..加载新内容。所以,避免这种情况的一种方法是用某些外部div包围您的{% include 'posts/comments.html' %},然后更改您的选择器,即:#${id}.comments > .yourouterdivclassname,这样新内容将仅在该div内加载,因此表单不会被删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接