一尘不染

如何使用ajax函数发送表单而不刷新页面,我缺少什么?是否必须使用rest-framework?

ajax

我正在尝试使用Ajax发送我的评论表单,现在当用户插入评论时,整个页面都会刷新。我希望在不刷新页面的情况下很好地插入它。所以我尝试了一堆东西,但是没有运气。因为我是初学者,所以我尝试了许多教程链接。
https://realpython.com/blog/python/django-and-ajax-form-submissions/

https://impythonist.wordpress.com/2015/06/16/django-with-ajax-a-modern-
client-服务器通信实践/ comment-page-1
/#comment-1631

我意识到我的问题是我很难在views.py和forms.py中处理我的代码,因此在进行客户端编程(js和ajax)之前,我需要再次设置后端(python代码)以进行设置阿贾克斯
有人可以帮我吗?我不知道如何设置我的后端。

  <div class="leave comment>
    <form method="POST" action='{% url "comment_create" %}' id='commentForAjax'>{% csrf_token %}
    <input type='hidden' name='post_id' value='{{ post.id }}'/>
    <input type='hidden' name='origin_path' value='{{ request.get_full_path }}'/>

    {% crispy comment_form comment_form.helper %}
    </form>
    </div>



<div class='reply_comment'>
    <form method="POST" action='{% url "comment_create" %}'>{% csrf_token %}
    <input type='hidden' name='post_id' id='post_id' value='{% url "comment_create" %}'/>
    <input type='hidden' name='origin_path' id='origin_path' value='{{ comment.get_origin }}'/>
    <input type='hidden' name='parent_id' id='parent_id' value='{{ comment.id }}' />
    {% crispy comment_form comment_form.helper %}

    </form>
    </div>

    <script>
     $(document).on('submit','.commentForAjax', function(e){
      e.preventDefault();

      $.ajax({
        type:'POST',
        url:'comment/create/',
        data:{
          post_id:$('#post_id').val(),
          origin_path:$('#origin_path').val(),
          parent_id:$('#parent_id').val(),
          csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
        },
        success:function(json){

我不知道该怎么办…我尝试了但失败了..这里发生了什么})

这是我的forms.py

class CommentForm(forms.Form):
    comment = forms.CharField(
        widget=forms.Textarea(attrs={"placeholder": "leave your thoughts"})
    )

    def __init__(self, data=None, files=None, **kwargs):
        super(CommentForm, self).__init__(data, files, kwargs)
        self.helper = FormHelper()
        self.helper.form_show_labels = False
        self.helper.add_input(Submit('submit', 'leave your thoughts', css_class='btn btn-default',))

和我的views.py

def comment_create_view(request):
    if request.method == "POST" and request.user.is_authenticated() and request.is_ajax():
        parent_id = request.POST.get('parent_id')
        post_id = request.POST.get("post_id")
        origin_path = request.POST.get("origin_path")
        try:
            post = Post.objects.get(id=post_id)
        except:
            post = None

        parent_comment = None
        if parent_id is not None:
            try:
                parent_comment = Comment.objects.get(id=parent_id)
            except:
                parent_comment = None

            if parent_comment is not None and parent_comment.post is not None:
                post = parent_comment.post

        form = CommentForm(request.POST)
        if form.is_valid():
            comment_text = form.cleaned_data['comment']
            if parent_comment is not None:
                # parent comments exists
                new_comment = Comment.objects.create_comment(
                    user=MyProfile.objects.get(user=request.user),
                    path=parent_comment.get_origin, 
                    text=comment_text,
                    post = post,
                    parent=parent_comment
                    )
                return HttpResponseRedirect(post.get_absolute_url())
            else:
                new_comment = Comment.objects.create_comment(
                    user=MyProfile.objects.get(user=request.user),
                    path=origin_path, 
                    text=comment_text,
                    post = post
                    )
                return HttpResponseRedirect(post.get_absolute_url())
        else:
            messages.error(request, "There was an error with your comment.")
            return HttpResponseRedirect(origin_path)

    else:
        raise Http404

即使阅读了有关它的教程,我仍然对使用ajax的想法感到不满意… json如何发挥作用,我也应该如何修改views.py
....有人可以解释一下它们如何组合在一起吗?并帮助我完成此任务…

    else:
        raise Http404

阅读 218

收藏
2020-07-26

共1个答案

一尘不染

完全检查您的代码并与OP进行深入讨论之后。我设法解决了运营问题。

  1. 删除后,HttpResponseRedirect我首先将其转换为JsonResponse并进行了相应的更改。

    response_data = {
                     "status":200, "message":"comment_stored", 
                     "parent": True, 
                     "parent_id": parent_comment.id,
                     "comment_count": parent_comment.comment_count()
                 }
    

    return JsonResponse(response_data)

  2. 下一步是简单地执行DOM操作以显示从响应中获取的数据。但是事实证明,这比预期的要复杂。因此,为简化起见,我将模板分为两部分-一部分将是主要部分,另一部分仅包含注释的HTML。

使用,django.template.loader.render_to_string我生成了所需的HTML以显示注释,并与响应一起以JSON中的字符串形式发送。

    html = render_to_string('main/child_comment.html', 
                                 {'comment': [new_comment], 
                                  'user': request.user, 
                                  'comment_form':comment_form
                        })
response_data = { 
                    "status":200, "message":"comment_stored", 
                    "comment":html, 
                    "parent": True, "parent_id": parent_comment.id,
                    "comment_count": parent_comment.comment_count()
                }
return JsonResponse(response_data)
  1. 最后,在主要在DOM操作脚本和一种表单模型中进行了较小的更改(与当前问题无关)之后,代码按预期工作。
    $('form').submit(function(e) {
    e.preventDefault();
    if ($(this).parents("tr") != 0) {
        parent_id = $(this).parents("tr").attr("id").split("_")[1];
        data_str = $(this).serialize() + "&parent_id=" + parent_id;
    } else {
        data_str = $(this).serialize();
    }
    $(this).parents("tr").attr("id").split("_")[1]
    $.ajax({
        type: 'POST',
        url: '{% url 'comment_create' %}',
        data: data_str,
        success: function(json) {
            alert(json.message);
            if (json.status == 200) {
                var comment = json.comment.trim();
                var user = json.user;
                if (!json.parent) {
                    $(comment).insertBefore('.table tr:first');
                } else {
                    $(comment).insertBefore('#comment_' + json.parent_id + ' #child_comment:first');
                    $(".replies").text("답글" + json.comment_count + "개 모두 보기");
                }
            }
    
        },
        error: function(response) {
            alert("some error occured. see console for detail");
        }
    });
    

    });

2020-07-26