代码之家  ›  专栏  ›  技术社区  ›  William

Django Ajax表单提交错误重定向到其他页面

  •  1
  • William  · 技术社区  · 7 年前

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

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

    ,但不停留在当前页面中。我希望页面保持在当前页面,并显示新的评论。

    以下是我的update\u评论视图:

    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 回复  |  直到 7 年前
        1
  •  2
  •   William    7 年前

    我终于成功了!感谢上帝!非常兴奋!

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

    第一:因为ajax会将news\u pk发布到视图中 update\u注释 ,因此我不需要在此视图的url和模板中添加news\u pk(在 <form> 标签和ajax中的url),所以我删除了它们,否则数据仍将通过表单传递,但不会通过ajax。

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

    第三个问题是我把“评论”和“评论”搞错了comment'是的name属性 <textarea> ,通过它形成。py获取数据。

    注释由ajax通过 var comments = $("#js-pl-textarea").val(), 所以在我看来我需要使用 comments = request.POST.get("comments", "") 但不要评论,这就是“post失败”的原因。

    下面是我的代码。

    以下是ajax:

     $("#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;
    
        });
    

    以下是我的udate\u注释视图:

    @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')
    

    这是我的模板表单:

    <form id="comment_form" action="{%  url 'operation:update_comment'%}" method="POST" >
    {% csrf_token %}
    
    <textarea id="js-pl-textarea"name="comment"></textarea>
    
    <input type="submit" value="Submit"> </input>
    
    </form>
    

    我真的很感谢大家的回复!通过你的回复,我一步一步地解决了这些问题!

        2
  •  1
  •   chidimo    7 年前

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

    1. ajax脚本。我把这个脚本放在一个名为 like_script.html .我使用django模板在模板中调用它 include

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

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

    url

    urlpatterns = path("like/", views.song_like_view, name='like_song'),
    
    1. 调用脚本的模板

        <a class="btn btn-sm btn-primary" href="" id="like" name="{{ song.pk }}" value="Like"></i> Unstar</a>
         {% include 'like_script.html' %}

    相似和不相似的按钮相同。我希望你能按照逻辑来做正确的事。请注意,在您的视图中,不需要包含pk。从 POST 数据 pk = request.POST.get('pk', None)