django实现点赞功能,classArtic


1,在文章模型中添加点赞字段,用多对多关系统计所有为文章点赞的用户。

class Article(BaseModel):
    ...
    # 为文章点赞
    users_like = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name="articles_like",
        verbose_name='点赞',blank=True)

2,编写处理函数

我这里只接收了需要点赞的文章id这个参数,至于如何判断该请求是点赞还是取消赞,

则是从对应文章的users_like中查询,如果已有记录,说明点过赞,那就进行取消赞操作,如果没有记录。那就将当前用户添加到文章记录中,实现点赞操作,然后再返回当前操作类型和点赞数,供前端进行显示渲染。

class LikeArticle(View):
    """
    点赞功能
    """
    def get(self, request):
        pass

    def post(self, request):
        try:
            user = request.user
            if user.is_authenticated:
                article_id = request.POST.get('article_id')
                article = Article.objects.filter(id=article_id)
                if article.exists():
                    user_like = article[0].users_like.filter(id=user.id)
                    # 查询当前用户是否为当前文章点过赞
                    type = 1
                    if user_like.exists():
                        # 若点过,则取消
                        article[0].users_like.remove(user)
                        type = 0
                    else:
                        # 若无,则点赞
                        article[0].users_like.add(user)
                    like_sum = article[0].users_like.count()
                    return JsonResponse({'state': 200, 'type': type, 'like_sum': like_sum})
            return JsonResponse({'state': 400, 'data': '点赞无效'})
        except Exception as e:
            return JsonResponse({'state': 500, 'data': f'出现异常:{e}'})

3,编写点赞路由

urlpatterns = [
    ...
    # 为文章点赞
    path(r'like_article/',
         views.LikeArticle.as_view(),
         name="like_article"),
]

4,前端页面部分

由于文章部分是由django模板语言渲染的,就不太好用vue再定义变量实现样式和点赞数的切换,

所以决定点赞按钮的初始化还是用django,只在点赞按钮上添加点击事件,

若点击,则会传递当前按钮节点和当前文章id到函数中。

{% if article.users_like.count > 0 %}
    <el-button @click="ck_like($event,{{ article.pk }})"
    icon="el-icon-caret-top" size="mini"
    {% if user in article.users_like.all %}
        type="primary"
    {% else %}
        plain
    {% endif %}
    >赞同 {{ article.users_like.count }}</el-button>
{% else %}
    <el-button @click="ck_like($event,{{ article.pk }})"
        icon="el-icon-caret-top" size="mini" plain>赞同</el-button>
{% endif %}

5,js部分

event.currentTarget这里实际上就是按钮的对象了,拿到id发送post请求,得到结果后

直接用js就能实现改变样式或者修改内部文字,达到局部刷新的效果。

ck_like(event,id){
    let like_btn = event.currentTarget
    var url = this.host+'/like_article/'
    var data = {
        'article_id': id,
    }
    $.ajax({
        url: url,
        type: 'post',
        data: data,
        success: function (res) {
            // console.log(res)
            if(res.state==200){
                like_btn.children[1].textContent = '赞同 '+res.like_sum
                if(res.type){
                    like_btn.className = 'el-button el-button--primary el-button--mini'
                }else{
                    like_btn.className = 'el-button el-button--default el-button--mini is-plain'
                }
            }else {
                index.$message.error({
                  message: res.data,
                });
            }
        },
        error: function (res){
            index.$message.error({
              message: res.data,
            });
        }
    })  
},

 

总结:

目前这个思路感觉还是不错的,哈哈

评论关闭