【问题标题】:DJango Ajax - Like button only changes in first post when clickedDJango Ajax - 点赞按钮仅在第一篇文章中单击时更改
【发布时间】:2020-05-01 12:19:00
【问题描述】:

我正在开发一个网站,用户可以在该网站上点赞帖子,并且我的主页上有所有用户帖子的列表。

我正在使用 Ajax 来防止在单击赞按钮时重新加载页面。我能够实现类似的视图,但我有一个问题。 Ajax 工作正常,但只有第一篇文章中的“赞”按钮在单击时会发生变化,从“赞”变为“不赞”。第二篇文章中的“赞”按钮没有改变。

我的代码如下:

@login_required
def home_view(request):
    #All posts in new feed
    all_images = Post.objects.filter(
        Q(poster_profile=request.user, active=True)|
        Q(poster_profile__from_user__to_user=request.user, active=True)|
        Q(poster_profile__to_user__from_user=request.user, active=True)|
        Q(poster_profile__profile__friends__user=request.user, active=True))

    #If post is liked displayed button
    posts = Post.objects.filter(pk__in=all_images)
    is_liked = {}
    for post in posts:
        if post.likes.filter(id=request.user.id).exists():
            is_liked[post.id] = True

   context = {'all_images': all_images, 'is_liked': is_liked}
   return render(request,'home.html', context)

   #Post likes
   @login_required
   def like_post_view(request):
       # post = get_object_or_404(Post, id=request.POST.get('post_id'))
       post = get_object_or_404(Post, id=request.POST.get('id'))
       is_liked = False
       if post.likes.filter(id=request.user.id).exists():
           post.likes.remove(request.user)
           is_liked = False
       else:
           is_liked = True
           post.likes.add(request.user)
       context = {'post': post, 'is_liked': is_liked,}
       if request.is_ajax():
           html = render_to_string('ajax_postlikes.html', context, request=request)
       return JsonResponse({'form': html})
       return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

模板:ajax_postlike.html

    <p>Like{{post.likes.count}}</p>

    <form action="{% url 'site:like_post' %}" method="POST">
    {% csrf_token %}
    {% if is_liked %}
    <button type="submit" name="post_id" value="{{ post.id }}" class="like float-left mr-2">
    Unlike
    </button>
    {% else %}
    <button type="submit" name="post_id" value="{{ post.id }}" class="like float-left mr-2">
    like
    </button>
    {% endif %}
    </form>

模板:home.html

    <div class="ml-1" id="like-section">
    {% include 'ajax_postlikes.html' %}
    </div>

Ajax/Jquery:

    <script type="text/javascript">
    $(document).on('click', '.like', function(event){
      event.preventDefault();
      var pk = $(this).attr('value');
      $.ajax({
        type: 'POST',
        url: "{% url 'site:like_post' %}",
        data: {'id':pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
        dataType: 'json',
        success: function(response) {
          $('#like-section{{ post.id }}').html(response['form'])
          console.log($('#like-section{{ post.id }}').html(response['form']));
      },
      error: function(rs, e) {
      console.log(rs.resopnseText);
    },
   });
  });
 </script>

我需要做些什么来解决在单击事件后按钮状态不在“喜欢”和“不喜欢”之间切换的问题?

[![在此处输入图片描述][1]][1][1]:https://i.stack.imgur.com/X4MWc.jpg

【问题讨论】:

    标签: jquery django ajax


    【解决方案1】:

    home.html 模板具有“like-section”作为 ID,但您的 JQuery 选择器获取 $('#like-section{{ post.id }}') - 模板中缺少 post.id 可能这就是为什么只更新第一个帖子的原因。

    <div class="ml-1" id="like-section">
        {% include 'ajax_postlikes.html' %}
    </div>
    

    编辑: 因此,我重新创建了您的视图、模型等,并设法让它与一些更改一起工作。

    1. 我已更改 home.html 模板以包含 Django 模板语言 for 循环,我在您的原始代码中看不到这一点,因此不确定如何在模板中准确创建帖子。这种格式在加载页面和对单个like 进行 AJAX 调用时有效。我还对 AJAX 调用和响应的处理方式进行了一些更改,我注意到一些无法工作的杂散模板语言。
      <body>
        <div class="ml-1" id="like-section">
          {% for post in post_list %}
            {% include 'ajax_postlikes.html' %}
          {% endfor %}
        </div>
    
        <script type="text/javascript">
          $(document).on('click', '.like', function(event){
            event.preventDefault();
            var pk = $(this).attr('value');
    
            $.ajax({
              type: 'POST',
              url: "{% url 'like_post_view' %}",
              headers: { 'X-CSRFToken': $('input[name=csrfmiddlewaretoken]').val() },
              data: {id: pk},
              success: function(response) {
                $('#like-section'+pk).html(response)
              },
              error: function(rs, e) {
                console.log(rs.responseText);
              },
             });
          });
        </script>
      </body>
    
    1. 我还更改了 ajax_postlikes.html 格式,我想您已经这样做了,但是我在表单中添加了一个 ID。我还更改了视图中解释的 if/else 语句的工作方式。
    <form id='like-section{{ post.id }}' action="{% url 'like_post_view' %}" method="POST">
    {% csrf_token %}
    {% if post.liked_by_user %}
    <button type="submit" name="post_id" value="{{ post.id }}" class="like float-left mr-2">
    Unlike
    </button>
    {% else %}
    <button type="submit" name="post_id" value="{{ post.id }}" class="like float-left mr-2">
    Like
    </button>
    {% endif %}
    </form>
    
    1. 这是 views.py 中的主视图 - 您可以向 QuerySet 对象添加一个变量,然后可以在模板中引用该变量(如上所示),而不是为 is_liked 设置一个变量并将两者分开。
    def home_view(request):
        posts = Post.objects.all()
    
        for post in posts:
            print(post)
            print(post.likes.filter(user=request.user).exists())
            if post.likes.filter(user=request.user).exists():
                post.liked_by_user = True
            else:
                post.liked_by_user = False
    
        context = {'post_list': posts}
        return render(request, 'home.html' , context)
    
    1. 最后,我按照同样的思路更新了 AJAX 视图。
    def like_post_view(request):
       post = get_object_or_404(Post, id=request.POST.get('id'))
    
       if post.likes.filter(user=request.user).exists():
           Like.objects.filter(post=post,user=request.user).delete()
           post.liked_by_user = False
       else:
           Like.objects.create(post=post, user=request.user)
           post.liked_by_user = True
    
       context = {'post': post}
    
       if request.is_ajax():
           return render(request, 'ajax_postlike.html', context)
    
       return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
    

    这对我有用,并在单击每个按钮时更新按钮(即表单)。我意识到我已经删除了一些过滤和其他模型逻辑,但应该很容易重新添加。

    【讨论】:

    • @OsVoid...同样的错误。只有第一个赞按钮切换。
    • @OsVoid ...如果我使用 class="like-section" 和 class="like"。当我在第一个帖子上单击“赞”按钮时,第二个帖子的“赞”按钮会与第一个帖子的按钮切换。但是只有第一个喜欢的帖子被保存在数据库中,我如何只为我点击的特定帖子按钮实现点赞按钮。您认为这可能是模板问题吗?
    • 如果 ID 更改没有修复它,那么它可能在视图中。页面第一次加载时是否正常工作,所以忽略 AJAX 调用?
    • @OsVoid...是的,它在没有 Ajax 的情况下正常工作,当我用我的代码实现 Ajax 时出现此错误
    • 模板看起来没有任何问题,所以必须在视图中 - 我会在前端记录帖子、is_liked、上下文和响应,并确保一切顺利正如预期的那样,使用正确的 ID
    猜你喜欢
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多