Django Ajax表单错误地提交重定向到另一个页面

时间:2018-04-26 20:50:48

标签: ajax django-forms django-templates django-views

当我使用ajax在Django中提交评论表单时,页面将重定向到空白页面,向我显示成功数据:

{"status":"success", "msg":"添加成功"}

,但不是留在当前页面。我希望页面停留在当前页面并向我显示新评论。

这是我的update_comment视图:

def update_comment(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    comment_form = CommentForm(request.POST or None)
    if request.method == 'POST' and comment_form.is_valid():
        if not request.user.is_authenticated:
            return render(request, 'login.html', {})
        comments = comment_form.cleaned_data.get("comment")
        news_comment = NewsComments(user=request.user, comments=comments, news=news)
        news_comment.save()

    # return redirect(reverse('news:news_detail', kwargs={'news_pk': news.id}))
        return HttpResponse('{"status":"success", "msg":"添加成功"}', content_type='application/json')
    else:
        return HttpResponse('{"status":"fail", "msg":"添加失败"}', content_type='application/json')

这是我的ajax:

$(document).on('submit', 'comment_form', function(e){
        e.preventDefault();

        $.ajax({
            cache: false,
            type: "POST",
            url:"{% url 'operation:update_comment' news.id %}",
            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();//refresh current page.
                }

                },
        });
    });

这是我的表格:

<form id="comment_form" action="{%  url 'operation:update_comment' news.id %}" method="POST" >
{% csrf_token %}

<textarea id="comment_textarea"name="comment"></textarea>

<input type="submit" value="Submit"> </input>

</form>

2 个答案:

答案 0 :(得分:1)

我的项目中有类似的东西。它是一首喜欢歌曲的剧本。我现在要把相关的代码放在这里。

  1. ajax脚本。我将此脚本放在名为like_script.html的单独文件中。我使用django模板include
  2. 在模板中调用它

    &#13;
    &#13;
    <script>
        $('#like').click(function(){
              $.ajax({
                       type: "POST",
                       url: "{% url 'song:like_song' %}",
                       data: {'pk': $(this).attr('pk'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
                       dataType: "json",
                       success: function(response) {
                              alert(response.message);
                        },
                        error: function(rs, e) {
                               alert(rs.responseText);
                        }
                  }); 
            })
        </script>
    &#13;
    &#13;
    &#13;

    django视图

    import json
    from django.http import HttpResponse
    from django.contrib.auth.decorators import login_required
    from django.views.decorators.http import require_POST
    @login_required
    @require_POST
    def song_like_view(request):
        if request.method == 'POST':
            user = SiteUser.objects.get(user=request.user)
            pk = request.POST.get('pk', None)
            song = get_object_or_404(Song, pk=pk)
    
            if song.likes.filter(pk=user.pk).exists():
                song.likes.remove(user)
                song.like_count = song.likes.count()
                song.save(update_fields=['like_count'])
                message = "You unstarred this song.\n {} now has {} stars".format(song.title, song.like_count)
            else:
                song.likes.add(user)
                song.like_count = song.likes.count()
                song.save(update_fields=['like_count'])
                message = "You starred this song.\n {} now has {} stars".format(song.title, song.like_count)
        context = {'message' : message}
        return HttpResponse(json.dumps(context), content_type='application/json')
    

    网址

    urlpatterns = path("like/", views.song_like_view, name='like_song'),
    
    1. 调用脚本的模板
    2. &#13;
      &#13;
          <a class="btn btn-sm btn-primary" href="" id="like" name="{{ song.pk }}" value="Like"></i> Unstar</a>
           {% include 'like_script.html' %}
      &#13;
      &#13;
      &#13;

      相同的按钮用于和不同。我希望你能遵循逻辑,使你的权利。请注意,在您的视图中,您不需要包含pk。只需从POST数据pk = request.POST.get('pk', None)

      中获取即可

答案 1 :(得分:0)

最后我成功了!谢谢主!非常兴奋!

我之前的代码中有三个主要问题。

首先:由于ajax会将news_pk发布到视图 update_comment ,因此我不需要在此视图的网址和模板中添加news_pk(在{的网址中) {1}}标记和ajax中的url),所以我删除了它们,或者数据仍然会通过Form而不是ajax。

第二:我的绑定不正确,我在表单上有点击处理程序,它应该是一个提交处理程序。如果我将其绑定到按钮,那么我将使用单击处理程序。Ajax not work in Django post 但对于这一部分,我仍然有点困惑,在按钮峰值方式和表单提交方式之间。

第三个问题是我误解了评论&#39;并且评论&#39;。评论&#39;是<form>的name属性,forms.py通过该属性获取数据。

评论由ajax通过<textarea>定义,因此在视图中我需要使用var comments = $("#js-pl-textarea").val(),但不评论,这就是发布失败的原因&#39;。

以下是我的代码。

这是ajax:

comments = request.POST.get("comments", "")

这是我的udate_comment视图:

 $("#comment_form").submit(function(){
        var comments = $("#js-pl-textarea").val()

        $.ajax({
            cache: false,
            type: "POST",
            url:"{% url 'operation:update_comment' %}",
            data:{'news_pk':{{ news.pk }}, '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();//refresh current page.
                }

                },
        });
        return false;

    });

这是我在模板中的表单:

@login_required
def update_comment(request):
        news_pk = request.POST.get("news_pk", 0)
        comments = request.POST.get("comments", "")
        if int(news_pk) > 0 and comments:
            news_comments = NewsComments()
            news = News.objects.get(id=int(news_pk))
            news_comments.news = news
            news_comments.comments = comments
            news_comments.user = request.user
            news_comments.save()
            return HttpResponse('{"status":"success", "msg":"添加成功"}', content_type='application/json')
        else:
            return HttpResponse('{"status":"fail", "msg":"添加失败"}', content_type='application/json')

我非常感谢大家的回复!有了你的回复,我一步一步地想出了这个问题!