【问题标题】:Can not get comment id with AJAX in django无法在 django 中使用 AJAX 获取评论 ID
【发布时间】:2022-01-08 09:31:11
【问题描述】:

我在几天内都在与这个问题作斗争,但找不到适合我的情况的解决方案。我正在尝试在不刷新页面的情况下制作喜欢系统。在喜欢和不喜欢的同步模式下工作正常,但是当我尝试添加 AJAX 时,我得到 405,并且只有最后一条评论可以单击,我理解 Ajax 不理解 django url 的问题或 pk 喜欢我的变体 {% url 'store:like' comment.pk %} ,但如何解决?

模板中有这部分:

{% 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 id="like-{{comment.pk}}" method="POST" action="{% url 'store:add_like' comment.pk %}">
                    {% csrf_token %}

                    <button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
                        <a class="btn btn-success" id="like-count-{{comment.pk}}"> Likes {{ comment.likes.all.count }}</a>
                    </button>
                </form>
        

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

        {% endfor %}

我在同一个模板中的 ajax 调用:

<script type="text/javascript">
    $(document).ready(function(){

        

  $('[id^="like-"]').submit(function(e){

            e.preventDefault();
            var endpoint = $(this).attr('action');
            var serializedData = $(this).serializeArray();
      $.ajax({
               type: 'POST',
               url: endpoint,
               data: serializedData,
               success: function(response) {
                     $( "#like-count-"+response["id"].toString()).text("Likes "+response["like_count"]);

                },
                error: function(rs, e) {
                       alert(rs.responseText);
                }
          });
    })

这部分来自网址:

path('products/<int:pk>/like/', addlike, name='like'),

查看喜欢:

@api_view(['POST'])
def addlike(request, pk, *args, **kwargs):

        is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
        if request.method == 'POST' and is_ajax:
            
            post = Comment.objects.get(pk=pk)


            is_dislike = False

            for dislike in post.dislikes.all():
                if dislike == request.user:
                    is_dislike = True
                    break

            if is_dislike:
                post.dislikes.remove(request.user)

            is_like = False

            for like in post.likes.all():
                if like == request.user:
                    is_like = True
                    break

            if not is_like:
                post.likes.add(request.user)

            if is_like:
                post.likes.remove(request.user)

            all_post_likes = post.total_likes() (function from models)
            return JsonResponse({"success": True, "like_count": all_post_likes, "id": pk}, status=200)
        else:

            return JsonResponse({"success": False}, status=400)

如何强制 AJAX 调用 pk 我需要的东西? (终于找到了解决办法,更新了最终版本的代码)

【问题讨论】:

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


    【解决方案1】:

    去掉‍data-url‍并设置action属性,因为当你点击提交按钮时,默认情况下这个POST请求会被发送到当前的URL并且你会收到405状态码,但是如果你设置action 这个POST 请求将被发送到like url:

    <form id="like" method="POST" action="{% url 'store:like' comment.pk %}">
        {% csrf_token %}
         <input type="hidden" value="{{comment.pk}}" name="id">
         <input type="hidden" name="next" value="{{ request.path }}">
         <button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
         <a class="btn btn-success" id="like"> Likes {{ comment.likes.all.count }}</a>
         </button>
    </form>
            
    

    而在js中你可以得到这样的URL

    var endpoint = $(this).attr('action');
    

    更新

    所有表单都具有相同的“ID”,因此只执行第一个表单,其余表单不由 Ajax 管理,要解决此问题,您可以为表单赋予不同的ID(此条件也适用到a标签):

    <form id="like-{{comment.pk}}" method="POST" action="{% url 'store:like' comment.pk %}">
         {% csrf_token %}
         ........
         .....
         <a class="btn btn-success" id="likes-count-{{comment.pk}}"> Likes {{ comment.likes.all.count }}</a>
    
    

    您可以通过这种方式接收事件并更新喜欢的数量。

    $(document).ready(function(){
      $('[id^="like-"]').submit(function(e){
        e.preventDefault();
        var endpoint = $(this).attr('action');
        var serializedData = $(this).serializeArray();
         
        $.ajax({
           url: endpoint,
           method: "POST",
           data: serializedData,
           success: function(response){
             $("#likes-count-" + serializedData[1].value).text("Likes "+response["like_count"]);
           }
        });
      })
    });
    
    

    在视图中,您应该返回新的点赞数:

    return JsonResponse({"success": True, "like_count": new_like_count}, status=200)
    

    在success函数中你可以通过response获取新的数字,现在我们改变a标签的文本值来改变like count。

    ^= 表示:选择具有指定属性的元素 值正好以给定的字符串开头。 attributeStartsWith1

    【讨论】:

    • 我做到了,但仍然“XHRPOSThttp://127.0.0.1:8000/products/433/like/”响应仅返回页面上的最后一条评论并且不想为其他人工作,其实我还有一个不喜欢的动作,这两个动作之间会不会有一些误会?或者我需要用另一个名字来分隔它?
    • 我更新了答案,看看现在能用吗?
    • 它开始工作得更好了!)我现在可以点击每个comment.pk,但仍然存在一个问题,当我点击按钮时,如果以前喜欢它应该减少它,但在这种情况下我收到错误“视图 store.views.addlike 没有返回 HttpResponse 对象。”所以据我了解,在这种情况下它开始以旧的同步模式工作,但我不知道为什么。我也对视图做了一些更改,现在它得到了 pk 参数:``` def addlike(request, pk, *args, **kwargs): 并删除了 " pk = request.GET['id'] pk = request. POST.get('id')" ```
    • 在每个视图中,您必须返回一个响应。在这里,错误告诉您不要返回 HttpResponse。增加或减少点赞数后,必须返回包含新点赞数的 JsonResponse,然后从 Ajax 中的成功函数中获取它,您可以将按钮值替换为新值(新点赞数)。
    • 所有&lt;a&gt;标签都有相同的ID并且很难改变,要解决这个问题你仍然需要创建不同的ID,确保它们与表单的@不同987654341@,例如&lt;a id ="like-count-{{comment.pk}}"&gt; 可以是一个不错的选择,然后在Ajax里面把serialize转换成serializeArray ()(因为我要访问id)然后在success函数里面修改@987654346的值@tag(to change like count) 像这样:$("#like-count-" + serializedData[1].value).text("Likes " + response["like_count"]);现在它应该可以正常工作了。
    【解决方案2】:

    我认为你应该发送带有 ajax 请求的 csrf_token 添加 headers: { "X-CSRFToken": token } 到您的 ajax 请求中,“token 是 csrf_token”或将 @csrf_exempt 装饰器添加到您的函数中,但它会使您的视图对 CSRF 攻击不安全。

    你可以在这里找到更多信息https://docs.djangoproject.com/en/4.0/ref/csrf/

    【讨论】:

    • 我已经试过了,但是没用,我猜这里还有问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 2011-09-03
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多