点赞与踩灭
功能介绍:
1.当用户在登录状态下点击赞或者灭可以做相应的操作
2.点击赞过会显示"推荐成功",点击灭过会显示"反对成功"
3.重复操作会相示对应提示"您已经推荐过"或"您已经反对过"
4.使用Ajax实现
5.服务器端使用到的知识点:事务,ORM添加操作,ORM修改操作(F查询)
执行流程:
客户端遇到的问题:
1.如何点击一个div判断是赞还是灭操作,觖决方法为使用样式判断hasClass方法判断哪个标签中有相对应的样式类,hasClass返回布尔值,将返回值is_up,文章编号article_id,通过Ajax传递给服务器
2.服务器接收到传递的数据,进行处理(其中user.id)可以使用当前登录用户的id值user.pk,取得所有值后向数据库点赞表中添加一条新记录,点赞表使用联合组键如果重复添加会报错,这里可以使用try捕获下异常,同时在文章表中的相关字段也需要更新
3.添加数据,更新数据完成后,将标志位回传给浏览器这个可以根据个人定制,ret={'state':False,'flag':False},其中ret包含两个键值对
state:操作是否成功,True正常操作,False异常操作,flag:操作是否成功,True赞操作,False灭操作
4.浏览器接收到ret后进行判断如果state为真时再对flag进行判断,flag为真则显示点赞成功,否则点灭成功;state为假说明已经有点赞或者灭的操作,再对flag进行判断
5.在urls中添加一个路由
url(r"^poll/", views.poll, name="poll"),
代码部分
html代码
<h3>{{ article_obj.title }}</h3>
<div class="container-fluid">{{ article_obj.articledetail.content|safe }}</div>
{ % csr f_ token % }
<div id="div_digg">
<div class="digg diggit">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="digg buryit">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<!-- 这个clesrfix是清除浮动的操作,bootstrap自带的样式 -->
<div class="clearfix"></div>
<div class="diggword" id="digg_tips"></div>
</div>
<div class="clearfix"></div>
<hr>
JS代码
$("#div_digg .digg").on('click', function () {
if (username) {
// 查看标签是否存在diggit样式返回bool值
var is_up = $(this).hasClass("diggit");
// is_up判断是点赞还是灭
// article_id是当前文章id
$.ajax({
url: poll,
type: "post",
data: {
is_up: is_up,
article_id: article_id,
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
// 添加成功data.state为真
if(data.state) {
// 操作为赞操作
if(data.flag){
$("#digg_count").html(parseInt(up_count)+1);
$("#digg_tips").text("推荐成功");
// 操作为灭操作
}else{
$("#bury_count").html(parseInt(down_count)+1);
$("#digg_tips").text("反对成功");
}
// 添加失败data.state为假
}else{
if(data.flag){
$("#digg_tips").text("您已经推荐过");
}else{
$("#digg_tips").text("您已经反对过");
}
}
}
});
} else {
// 用户未登录
window.location.href = "/logIn/";
}
});
视图views
def poll(request):
"""
点赞操作
:param request:
:return:
"""
# ret两个键值对
# 1.state:操作是否成功,True正常操作,False异常操作
# 2.flag:操作是否成功,True赞操作,False灭操作
ret = {'state': False,'flag':False}
is_up = request.POST.get("is_up")
# 取出的is_up为布尔值,需要转换
is_up = json.loads(is_up)
article_id = request.POST.get("article_id")
# 用户ID可以直接取当前用户ID
user_id = request.user.pk
try:
# 添加事务
with transaction.atomic():
# 向点赞表中添加数据,
# 如果用户点赞,更新文章表up_count字段
# 如果用户点灭,更新文章表down_count字段
models.ArticleUpDown.objects.create(article_id=article_id, user_id=user_id, is_up=is_up)
if is_up:
# 返回值为影响的行数
c = models.Article.objects.filter(pk=article_id).update(up_count=F("up_count") + 1)
ret['flag'] = True
else:
c = models.Article.objects.filter(pk=article_id).update(down_count=F("down_count") + 1)
ret['state'] = True
except Exception as e:
print(e)
ret['flag'] = models.ArticleUpDown.objects.filter(article_id=article_id, user_id=user_id).first().is_up
return JsonResponse(ret)