如何通过 ajax 调用在不刷新的情况下在 django 站点上添加评论?

How to add comment on django site with ajax call and without refreshing?

网站上存在用户可以评论产品的表单。评论与产品相关联。 jQuery 从 Bootstrap base.html 中使用(它与另一个 ajax 调用一起使用)。我在本周与 ajax 评论作斗争)。尝试只为一种产品做这件事,以了解它是如何工作的。没有 ajax 评论系统工作正常,但我决定在不刷新页面的情况下在评论添加中添加平滑,我第一次使用 POST 和 ajax 执行任务(在我做之前两个非常简单的示例,在成功响应后端 ajax 后重置 get 和表单)。有人可以建议应该在模板和视图中添加什么吗?我想问题与我对js的了解不足有关。

我正在使用

is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

因为这是与 django 4.0 一起使用的,旧函数 is_ajax() 已被删除。

views.py

def ajax_test(request):
    product = Product.objects.get(id=4)
    comments = product.comment_set.order_by('-created_at')
    form = UserCommentForm

    context = {'product':product,'comments':comments,'form': form}
    return render(request, 'store/ajax_test.html', context)

def ajax_receiver(request):
    is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
    if request.method == 'POST' and is_ajax:
        product = Product.objects.get(id=4)
        form = UserCommentForm(data=request.POST)
        user = Comment.objects.get(author=user)
        if form.is_valid() and request.user.is_authenticated:
            new_comment = form.save(commit=False)
            new_comment.author = request.user
            new_comment.product = product
            new_comment.save()
            comment_info = {
            "author": new_comment.author,
            "new_comment": new_comment.content,
            "created_at": new_comment.created_at,
            }
            return JsonResponse({"comment_info": comment_info}, status=200)
    else:
        return JsonResponse({"success": False}, status=400)

模板

{% extends "store/base.html" %}
{% load bootstrap4 %}

{% block page_header %}
  <h1>тестирую аякс</h1>
{% endblock page_header %}

{% block content %}

<div class="container">
     <div class="row py-3">
         <div class="col-3 order-2" id="sticky-sidebar">
           <div class="sticky-top">
             <form id="UserCommentForm" method='post' class="form">
               {% csrf_token %}
               {% bootstrap_form form %}

               {% buttons %}
                 <button name="submit" class="btn btn-primary" name="comment">Добавить комментарий</button>
               {% endbuttons %}
           </form>
         </div>
       </div>
    <div class="col" id="main">
      <h3>Комментарии:</h3>
       {% for comment in comments %}
       <h6 class="card-header">
       {{ comment.author }}<small> добавлен {{ comment.created_at|date:'M d, Y H:i' }} </small>
       </h6>
        <div class="card-body">
        <h4>{{ comment }}</h4>
        <form action="" method="POST">
          {% csrf_token %}


         </form>

        </div>
        {% empty %}
        <p>Для данного товара  ещё нет комментариев.</p>

        {% endfor %}

              </div>
        </div>
    </div>

    {% block javascript %}
    <script type="text/javascript">
    $(document).ready(function(){
       $("#UserCommentForm").submit(function(e) {
          // prevent from normal form behaviour
          e.preventDefault();

          // serialize the form data
          var serializedData = $(this).serialize();

          $.ajax({
                type : 'POST',
                url :  "{% url 'store:ajax_receiver' %}",
                data : serializedData,
                success : function(response){
                
                    ??? what should be there to post ???
                },
                error : function(response){
                    console.log(response)
                }
            });
       });
    });
    </script>
    {% endblock javascript %}

{% endblock content %}

最后我找到了决定,它只是重新加载评论块而不刷新,有代码,'#main'之前的space很重要!:

<script type="text/javascript">
    $(document).ready(function(){
       $("#UserCommentForm").submit(function(e){
        // prevent from normal form behaviour

            e.preventDefault();
            // serialize the form data


            var serializedData = $(this).serialize();
            $.ajax({
                type : 'POST',
                url :  "{% url 'store:ajax_receiver' %}",
                data : serializedData,
                success : function(response){
                    $('#main').load(' #main', function(){
           /// can add another function here

      });
                    $("#UserCommentForm")[0].reset();

                },
                error : function(response){
                    console.log(response)
                }
            });
       });
    });
    </script>

在您的 ajax 成功中写入以下代码以显示新评论:

let comment_info = response["comment_info"];
let author = comment_info["author"];
let comment  = comment_info["comment"];
let created_at = comment_info["created_at"];
html = "<h6 class='card-header'> "+author+"</h6>"
// i have writting only part of html write the full just like you do when you show comments
$("#main").append(html);