Ajax not work in Django post

前端 未结 4 512
温柔的废话
温柔的废话 2021-01-17 01:53

I\'m trying to use ajax in Django to post comment in a news website.However it doesn\'t work.When I click the submit button,it still refreshes the page and make no d

相关标签:
4条回答
  • 2021-01-17 02:23

    Finally I made it!Thanks Lord!Very excited!Please check my detailed answer here:Django Ajax Form submit wrongly redirect to another page really appreciate everyone's reply!With your reply I figured out these issue step by step!

    0 讨论(0)
  • 2021-01-17 02:31

    This could work, it contains some suggestions from your codes.

    ++ newsDetailView
    ++ in news_details.html
    ++ in you scripts

    views.py

    def newsDetailView(request, news_pk):
        #news = News.objects.get(id=news_pk) No need to get the object like this anymore
        news = get_object_or_404(News,id=news_pk) #
        title = news.title
        author = news.author_name
        add_time = news.add_time
        content = news.content
        category = news.category
        tags = news.tag.annotate(news_count=Count('news'))
    
        comment_form = CommentForm(request.POST or None)
        if request.method == 'POST' and comment_form.is_valid():
            # if request.method == 'POST' and request.is_ajax() and comment_form.is_valid(): To make sure it's ajax
            if not request.user.is_authenticated:
                return JsonResponse({"msg":"You need to login",
                "url":'login_url','status':'login_required'})
            comments = comment_form.cleaned_data.get("comment")
            news_comment = NewsComments(user=request.user, comments=comments, news=news)
            news_comment.save()
    
        # This needs to be after request.POST process 
        all_comments = NewsComments.objects.filter(news=news) 
    
        context = {
            'title': title,
            'author': author,
            'add_time': add_time,
            'content': content,
            'tags': tags,
            'category': category,
            'all_comments': all_comments,
            'comment_form': comment_form,
        }   
        return render(request, "news_detail.html", context)
    

    news_detail.html | Form

    {% if user.is_authenticated %}
    <form id="js-pl-submit" method="POST" action="">{% csrf_token %}
        {% for field in comment_form %}
            {% for error in field.errors %}
            <div class="alert alert-warning text-center mb-3" role="alert">{{ error }}</div>
            {% endfor %}
        {% endfor %}
    </form>
    {% endif %}
    

    news_detail.html | Comments

    <div id="comments_section">
        {% for user_comments in all_comments %}
        <img class="mr-3 comment-avatar rounded-circle" src="{{ MEDIA_URL }}{{ user_comments.user.image }}" alt="Generic placeholder image">
        <div class="media-body">
            <h6 class="mt-0 mb-1">{{ user_comments.user.username }}</h6>
            {{ user_comments.comments }}
        </div>
        <span>{{ user_comments.add_time }}</span>
        {% endfor %}
    </div>
    

    JS script

    $(document).on('submit','#js-pl-submit',function(){ // Correction : Not click, but submit
        var comments = $("#js-pl-textarea").val()
        if(!comments){
            alert("评论不能为空")
            return false
        }
        $.ajax({
            cache: false,
            type: "POST",
            url:"",
            data:{
                // 'news_pk':{{ news.id }}, No need to send the news.id
                /// you are actually on the instance of `news` Object 
                'comments':comments,
                'csrfmiddlewaretoken':$("input[name=csrfmiddlewaretoken]").val(), // retrieve `csrf_token` from `form`
            },
            async: true,
            success: function(data) {
                // Not sure it's the more powerful, but this should work like a charm
                if(data.status == 'login_url'){
                    alert(data.msg);
                    window.location.href = data.url;
                }
                // Those 2 next lines are useful if you want to refresh without reload the page.
                $("#js-pl-submit").replaceWith($('#js-pl-submit',data));//刷新当前页面.
                $("#comments_section").replaceWith($('#comments_section',data));
                // This next line will reload the page
                windows.location.reload();
    
            },
            error:function(){
                // Codes here in case of error
            },
            statusCode:{
                404:function(){
                    alert("Object not found");
                },
                500:function(){
                    alert("An error has occured on the server");
                },
            }
        });
        return false;
    });
    

    Feel free to comment, so that I can edit my answer, to help you succeed.

    0 讨论(0)
  • 2021-01-17 02:34

    Your binding is incorrect, you have the click handler on the form it should be a submit handler. If you were binding it to a button then you'd use click a handler.

    $('#js-pl-submit').on('submit', function(){//<-- here
        var comments = $("#js-pl-textarea").val()
        if(comments == ""){
            alert("评论不能为空")
            return false
        }
        $.ajax({
            cache: false,
            type: "POST",
            url:"",
            data:{'news_pk':{{ news.id }}, 'comments':comments},
            async: true,
            beforeSend:function(xhr, settings){
                xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
            },
            success: function(data) {
                if(data.status == 'fail'){
                    if(data.msg == '用户未登录'){
                        window.location.href="login";
                    }else{
                        alert(data.msg)
                    }
                }else if(data.status == 'success'){
                    window.location.reload();//刷新当前页面.
                }
            },
        });
        return false;
    });
    
    0 讨论(0)
  • 2021-01-17 02:45

    Add click event on button not on form and You have to change that to button implicitly. By default the type of a button is submit.

    <form method="POST" action="">
    <button type="button" id="js-pl-submit"> 
    

    Remove id of form. Submit button submits form-data and reload the page.

    0 讨论(0)
提交回复
热议问题