6.博客系统| 点赞功能
1.点赞样式的构建/点赞事件的绑定
点赞人即当前登录人;评论人即当前当前登录人。
article_detail.html
{% extends "base.html" %} {% block content %} {# {% load my_tags %}#} {# {% multi_tag 3 9 %}#} <div class="article_info"> <h3 class="text-center title">{{ article_obj.title }}</h3> //文章标题 <div class="cont"> //文章内容 {{ article_obj.content |safe }} {# 加这个是为了告诉django的模板不要给我做任何转义,为了安全性#} </div> <div id="div_digg" > //点赞 ,这一套点赞,再给它们加上样式 <div class="diggit action"> //点赞, <span class="diggnum" id="digg_count">{{article_obj.up_count}}</span> //不要把点赞数写成1,这样就写死了 </div> <div class="buryit action"> //踩灭;要给点赞和踩灭同时绑定ajax,同时起个名字action <span class="burynum" id="bury_count">{{article_obj.down_count}}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div>
</div> <script> $("#div_digg .action").click(function(){ var is_up = $(this).hasClass("diggit"); //怎么写,点击 diggit action的时候是True;点击 buryit action的时候是False。判断它们的class值 alert(is_up) }) </script> {% endblock %}
<script> $("#div_digg .action").click(function(){ var is_up = $(this).hasClass("diggit"); $.ajax({ url:"/digg/", #构建路径,加上路径路由 type:"post", data:{ //作为键,一组键值。 "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val(), "is_up":is_up, "article_id":"{{ article_obj.pk }}", //没必要把user传进来,在视图中我们用的是用户认证登录组件,直接对应的是request.user就是当前登录人,其实就是当前点赞人和登录人。根本没必要传在session里边就取出来了。 }, success: function (data) { console.log(data); } }) }) </script>
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link type="text/css" rel="stylesheet" href="/static/blog/css/home_site.css"> <link type="text/css" rel="stylesheet" href="/static/blog/css/article_detail.css"> <link type="text/css" rel="stylesheet" href="/static/blog/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-3.2.1.min.js"></script> //先引入它 </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3 menu" > {% load my_tags %} {% get_classification_style username %} </div> <div class="col-md-9"> {% block content %} {# 写个块留着扩展用#} {% endblock %} </div> </div> </div> </body> </html>
article_detail.css(点赞样式的)
.article_info .title{ margin-bottom: 20px; } #div_digg { //父亲的 float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; width: 125px; text-align: center; margin-top: 10px; } .diggit { //推荐的 float: left; width: 46px; height: 52px; background: url("/static/font/upup.gif") no-repeat; //把图片的静态文件下载到本地,博客它做反爬虫了 text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px; } .buryit { //反对的 float: right; margin-left: 20px; width: 46px; height: 52px; background: url("/static/font/downdown.gif") no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px; } .clear { clear: both; //清除浮动 }
哪个用户对那篇文章进行了点赞,发Ajax请求,发生True or False
home_site.css
*{ margin:0; padding:0; } .header{ width:100%; height: 60px; background-color: #369; } .header .title{ font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px;; } .backend{ float:right; color: white; text-decoration: none; font-size: 16px; margin-right:10px; margin-top: 10px;; } .pub_info{ margin-top: 10px; color: darkgrey; } .menu{ margin-top: 20px; }
2. 文章点赞的保存
views.py
#点赞 import json def digg(request): print(request.POST) article_id = request.POST.get("article_id") #应该传布尔值,反序列化下,而不是字符串 is_up = json.loads(request.POST.get("is_up")) #它拿到的是字符串“True”,传的时候永远是一个真值,要反序列化传一个布尔值; #点赞人即当前登录人 user_id = request.user.pk ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id,is_up=is_up) return HttpResponse("ok")
点赞————>>>
3. 文章点赞数的数据同步
再次访问点赞这个页面时,应该保持这个点赞数。--->>> 在创建点赞记录的时候同时也要对文章进行更新。
#点赞 import json from django.db.models import F def digg(request): print(request.POST) article_id = request.POST.get("article_id") is_up = json.loads(request.POST.get("is_up")) #字符串的“True”,是一个布尔值 #点赞人即当前登录人 user_id = request.user.pk ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id,is_up=is_up) queryset = models.Article.objects.filter(pk=article_id) #拿到这篇文章 if is_up: queryset.update(up_count=F("up_count")+1) #对这篇文章点赞数进行更新 else: queryset.update(down_count=F("down_count")+1) return HttpResponse("ok")
4. 文章点赞的提示重复操作
#点赞 import json from django.db.models import F from django.http import JsonResponse def digg(request): print(request.POST) article_id = request.POST.get("article_id") is_up = json.loads(request.POST.get("is_up")) #字符串的“True”,是一个布尔值 #点赞人即当前登录人 user_id = request.user.pk obj = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first() //过滤,用户对文章做了什么操作; 拿到这个对象。 response={"state":True} #默认True if not obj: ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id,is_up=is_up) queryset = models.Article.objects.filter(pk=article_id) if is_up: queryset.update(up_count=F("up_count")+1) else: queryset.update(down_count=F("down_count")+1) else: response["state"] = False #True表示你已经赞支持过了,False表已经踩过了 response["handled"] = obj.is_up #字典再加一个信息;过滤出的obj拿到is_up return JsonResponse(response)
article_detail.html
<script> $("#div_digg .action").click(function(){ var is_up = $(this).hasClass("diggit"); $.ajax({ url:"/digg/", type:"post", data:{ //作为键,一组键值。 "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val(), "is_up":is_up, "article_id":"{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state){ //提交成功了 } else{ if(data.handled){ $("#digg_tips").html("您已经推荐过!") }else { $("#digg_tips").html("您已经反对过!") } setTimeout(function () { $("#digg_tips").html("") },1000) } } }) }) </script>
5. 文章点赞数的Ajax更新
渲染有两种方式: render的渲染(刷新页面)、Ajax的dom显示(局部刷新),
<script> $("#div_digg .action").click(function(){ var is_up = $(this).hasClass("diggit"); $.ajax({ url:"/digg/", type:"post", data:{ //作为键,一组键值。 "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val(), "is_up":is_up, "article_id":"{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state){ if (is_up){ var val = parseInt($("#digg_count").text()); //取值,parseInt相当于python中的int ; $("#digg_count").text(val+1); //赋值。 }else { var val=parseInt($("#digg_count").text()); $("#bury_count").text(val+1); } } else{ if(data.handled){ $("#digg_tips").html("您已经推荐过!") }else { $("#digg_tips").html("您已经反对过!") } setTimeout(function () { $("#digg_tips").html("") },1000) } } }) }) </script>
代码的优化
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<script> $("#div_digg .action").click(function(){ var is_up = $(this).hasClass("diggit"); $obj=$(this).children("span"); $.ajax({ url:"/digg/", type:"post", data:{ //作为键,一组键值。 "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val(), "is_up":is_up, "article_id":"{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state){ var val=parseInt($obj.text()); $obj.text(val+1) {# if (is_up){#} {# var val = parseInt($("#digg_count").text());#} {# $("#digg_count").text(val+1);#} {# }else {#} {# var val=parseInt($("#digg_count").text());#} {# $("#bury_count").text(val+1);#} {# }#} } else{ var val = data.handled ? "您已经推荐过!":"您已经反对过!"; //三元运算 $("#digg_tips").html(val); {# if(data.handled){#} {# $("#digg_tips").html("您已经推荐过!")#} {# }else {#} {# $("#digg_tips").html("您已经反对过!")#} {# }#} setTimeout(function () { $("#digg_tips").html("") },1000) } } }) }) </script>