【问题标题】:Djnago post "like" functionality issueDjango发布“喜欢”功能问题
【发布时间】:2020-10-31 03:47:03
【问题描述】:

我在帖子列表页面(显示单个用户的帖子)中构建了帖子“喜欢”功能。使用“示例中的 Django”一书中的示例,我在每个帖子下面都做了 ajax 之类的按钮。但它工作不正确。在该示例中,类似按钮是为单个帖子页面制作的,我尝试将其用于帖子列表页面(一页中有很多帖子)。当按下数据库中的“赞”按钮时,一切都很好——我得到了一个对特定帖子的赞。但是在前端,事情发生了——所有帖子的点赞数都在变化,就好像所有帖子都是连接的。当我点赞和不赞时,所有帖子的点赞数都会变成一些大值。我认为这是因为在这种情况下,Ajax 对所有帖子使用相同的类选择器(而不是 id)。我仍然不太擅长 Django 和 Ajax,并且无法找到一种方法来使其正常工作。花了很长时间试图解决这个问题并在谷歌搜索中没有结果。有任何帮助。

下面是代码。

带有点赞字段的帖子模型:

class Posts(models.Model):
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True, blank=True)
    content = models.TextField()
    image = models.ImageField(upload_to="posts/%Y/%m/%d", null=True,blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                        related_name='images_liked',
                                        blank=True)
    total_likes = models.PositiveIntegerField(db_index=True,
                                              default=0)

    def __str__(self):
        return self.title

     
    def get_absolute_url(self):
        return reverse("post_detail", kwargs={"slug": self.slug})


def slug_generator(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)


pre_save.connect(slug_generator, sender=Posts)

用户view.py中的post_like函数:

@ajax_required
@login_required
@require_POST
def post_like(request):
    post_id = request.POST.get('id')
    action = request.POST.get('action')
    if post_id and action:
        try:
            post = Posts.objects.get(id=post_id)
            if action == 'like':
                post.users_like.add(request.user)
                create_action(request.user, 'likes', post)
            else:
                post.users_like.remove(request.user)
            return JsonResponse({'status':'ok'})
        except:
            pass
    return JsonResponse({'status':'ok'})

urls.py 中的代码:

urlpatterns = [
    
    path('like/', views.post_like, name='like'),
...another urls...
]

点赞按钮和点赞计数的 html:

{% with total_likes=post.users_like.count users_like=post.users_like.all %}
    <div class="image-info">
      <div>
        <span class="count">
         <span class="total">{{ total_likes }}</span>
         like{{ total_likes|pluralize }}
        </span>
        
        <a href="#" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
          {% if request.user not in users_like %}
            Like
          {% else %}
            Unlike
          {% endif %}
        </a>
      </div>
      
    </div>
    <div class="image-likes">
     
     
    </div>
  {% endwith %}

在同一个 html 文件中,按钮所在的位置,底部是点赞功能的 ajax 代码:

{% block domready %}
$('a.like').click(function(e){
    e.preventDefault();
    
    $.post('/like/',
      {
        id: $(this).data('id'),
        action: $(this).data('action')
      },
      function(data){
        if (data['status'] == 'ok')
        {
          var previous_action = $('a.like').data('action');

          // toggle data-action
          $('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
          // toggle link text
          $('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');

          // update total likes
          var previous_likes = parseInt($('span.count .total').text());
          $('span.count .total').text(previous_action == 'like' ? previous_likes + 2 : previous_likes - 2);
          
        }
      }
    );
    
  });
{% endblock %}

【问题讨论】:

    标签: django django-models django-views django-templates likebtn


    【解决方案1】:

    您只想修改已单击的赞按钮,方法是将其放入您的click 函数中。您可以稍微整理一下您的代码,但为了保持相似,您可以执行以下操作:

    $('a.like').click(function(e){
        e.preventDefault();
        // Get the clicked button.
        const $clickedButton = $( this );
        
        $.post('/like/',
            {
                id: $clickedButton.data('id'),
                action: $clickedButton.data('action')
            }, 
            function(data) {
                if (data['status'] == 'ok') {
                    // Update the clicked button only.
                    var previous_action = $clickedButton.data('action');
                    
                    // toggle data-action
                    $clickedButton.data('action', previous_action == 'like' ? 'unlike' : 'like');
                    // toggle link text
                    $clickedButton.text(previous_action == 'like' ? 'Unlike' : 'Like');
    
                    // update total likes
                    const $total = $clickedButton.prev('span.count').children('.total');
                    var previous_likes = parseInt($total.text());
                    $total.text(previous_action == 'like' ? previous_likes + 2 : previous_likes - 2);
                }
            }
        );
    });
    

    我不是 100% 确定您为什么要从总数中加/减 2 而不是 1,但我没有足够的上下文。

    【讨论】:

    • 感谢您的回答。我按照你展示的方式做了。但是当我点击 Like 按钮时,前端没有任何变化。重新加载页面时,比是的,我在 db 中更喜欢。但是 ajax 停止工作。
    • 在我的 ajax 版本中 - 当我点击喜欢时,“喜欢”文本变为“不喜欢”(切换),这是正确的,但喜欢的数量正在以某种奇怪的方式增加。所有帖子的喜欢都会发生这种情况(他们都获得相同数量的喜欢。例如:我点击帖子 A 的点赞按钮,然后对于帖子 A、B、C,文本从“喜欢”变为“不喜欢”,并且例如,点赞数从 0 变为 9。当我点击帖子 A 上的不同时,所有帖子的文本都变为喜欢,点赞数变为 130。
    • 当我重新加载页面时一切正常 - 我只喜欢喜欢的帖子。看起来有些东西正在打破 ajax。
    • 查看这个 JSFiddle:jsfiddle.net/er98kntz 我已经去掉了 Ajax 调用,但它似乎可以满足您的要求?虽然我仍然不确定 +/- 2。我认为应该是 1。
    • 谢谢!我会查一下。 +/- 2 只是玩数字。它应该是 +/-1。我改变了,但这不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2018-06-26
    • 2013-10-23
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多