bbs--点赞
bbs---点赞
需求分析
页面展示
1 点赞 和 踩灭 按钮展示
1 用户未登录,不处理点赞踩灭,给用户提供登录接口
2 登录
1 第一次点点赞/踩灭
1 点赞成功 数据+1 提示点赞成功
2点赞失败 数据+1 提示踩灭成功
2 第二/n次点点赞/踩灭
1 点击点赞/踩灭,提示已点赞/踩灭过
代码思路
1 html页面结构
页面展示
1 在文章视图函数中传入从orm中查询到的该文章的对象
2 在html中,通过模板语法,取到点赞数和踩灭数
点赞 {{ article.up_count }}
踩灭 {{ article.up_count }}
用户点赞/踩灭
1 由于点击不能确定点赞还是踩灭,我们把点赞和踩灭绑定统一个事件--------通过绑定同一个类完成
2 判断用户有没有登录
没登录:跳转到登录页面,并且把当前的url传过去,方便登录后跳转回来
登录:执行下面的
3 获取 文章id 用户id 点赞/踩灭
文章id '{{ article.id }}'
用户id '{{ request.user.id }}'
点赞/踩灭:通过获取点赞/踩灭特有的类,能否取到值来判断 然后通过三元运算 赋值 True /False
4 ajax通过post请求把数据传给后端
5 后端 赋值状态码 获取 文章id 用户id 点赞/踩灭状态
文章id
用户id
点赞/踩灭状态:坑1
6 通过文章id 用户id 取值判断用户是否点赞/踩灭过
未点赞/踩灭过
赋值状态码 添加点赞/踩灭记录 跟新文章的点赞/踩灭字段 ----------这里要用事务
点赞/踩灭过
赋值状态码 和 错误信息 返回
坑:
1 通过ajax 传的True/False 时‘True’/'False',所以我们要通过三元运算重新赋值True/Flase
实际操作
html
<!-- 点赞 开始--> <div class="clearfix"> <div id="div_digg"> <!-- 点赞 --> <div class="diggit digg"> <span class="diggnum" id="digg_count">{{ article.up_count }}</span> </div> <!-- 反对 --> <div class="buryit digg"> <span class="burynum" id="bury_count">{{ article.down_count }}</span> </div> <div class="clear"></div> <!-- 提示信息 --> <div class="diggword" id="digg_tips"></div> </div> </div> <!-- 点赞 结束--> <script> // 给点赞和反对按钮绑定点击事件 $(".digg").click(function () { // 1. 先判断有没有登录? if (!'{{ request.user.username }}') { // 如果没有登录就跳转到登录页面 location.href = '/login/?next={{ request.get_full_path }}' } // 已经登录可以点赞或反对 var userId = '{{ request.user.id }}'; var articleId = '{{ article.id }}'; // 如何区分是点赞还是反对? var isUp = $(this).hasClass('diggit'); // 向后端发请求 $.ajax({ url: '/mengmeng/', type: 'post', data: { csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val(), userId: userId, articleId: articleId, isUp: isUp }, success: function (res) { console.log(res); if (res.code !== 0) { // 只需要把错误提示显示出来就可以 $("#digg_tips").text(res.msg); } else { // 1. 先把点赞数或反对数更新一下 if (isUp) { // 更新点赞数 var $UpSpan = $("#digg_count"); $UpSpan.text(+$UpSpan.text() + 1); } else { var $downSpan = $("#bury_count"); $downSpan.text(+$downSpan.text() + 1) } // 2. 再显示提示 $("#digg_tips").text(res.msg); } } }) }); </script>
views
# 点赞 def mengmeng(request): if request.method == "POST": res = {"code": 0} print(request.POST) user_id = request.POST.get("userId") article_id = request.POST.get("articleId") is_up = request.POST.get("isUp") print(is_up, type(is_up)) is_up = True if is_up.upper() == 'TRUE' else False # 5.不能给自己点赞 article_obj = models.Article.objects.filter(id=article_id, user_id=user_id) if article_obj: # 表示是给自己写的文章点赞 res["code"] = 1 res["msg"] = '不能给自己的文章点赞!' if is_up else '不能反对自己的内容!' # 3.同一个人只能给同一篇文章点赞一次 # 4.点赞和反对两个只能选一个 # 判断一下当前这个人和这篇文章 在点赞表里有没有记录 is_exist = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first() if is_exist: res["code"] = 1 # 表示已经点赞过或反对过 # if is_exist.is_up == True: # # 已经点过赞 # res["msg"] = '已经点过赞' # else: # # 已经反对过 # res["msg"] = '已经反对过' res["msg"] = '已经点过赞' if is_exist.is_up else '已经反对过' else: # 真正点赞 # 注意? # 事务操作,, with transaction.atomic(): # 1. 先创建点赞记录 models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up) # 2. 再更新文章表 if is_up: # 更新点赞数 models.Article.objects.filter(id=article_id).update(up_count=F('up_count')+1) else: # 更新反对数 models.Article.objects.filter(id=article_id).update(down_count=F('down_count') + 1) res["msg"] = '点赞成功' if is_up else '反对成功' return JsonResponse(res)