1、文章详情页的设计
# 文章详情页 re_path(r'^(?P<username>w+)/articles/(?P<article_id>d+)$', views.article_detail, name='article_detail'),
2、文章详情页的数据构建
def article_detail(request, username, article_id): """文章详情页""" user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog # 查询当前站点对象 article_list = models.Article.objects.filter(user=user_obj) cate_list = models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count("article__title")).values_list("title", 'c') tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(c=Count('article')).values_list('title','c') date_list = models.Article.objects.filter(user=user_obj).extra(select={'y_m_date':"date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(c=Count('nid')).values_list('y_m_date', 'c') return render(request,'blog/article_detail.html',{"username":username,'blog':blog,'article_list':article_list,"tag_list":tag_list,"date_list":date_list, "cate_list":cate_list})
1、解决复用问题:方式1:封装函数
3、解决复用问题:方式2:inclution_tag 自定义tag
1、自定义的simple_tag
2.inclution_tag
# -*- coding: utf-8 -*- # @Time : 2018/08/04 0004 22:03 # @Author : Venicid from django import template from django.db.models import Count from blog import models register = template.Library() @register.simple_tag def multi_tag(x,y): return x*y @register.inclusion_tag("blog/classification.html") def get_classification_style(username): user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog cate_list = models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count("article__title")).values_list("title", 'c') tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(c=Count('article')).values_list('title','c') date_list = models.Article.objects.filter(user=user_obj).extra(select={'y_m_date':"date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(c=Count('nid')).values_list('y_m_date', 'c') return {'blog':blog,"tag_list":tag_list,"date_list":date_list, "cate_list":cate_list}
4、标签字符串转义
def article_detail(request, username, article_id): """文章详情页""" user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog # article_id对应的文章 article_obj = models.Article.objects.filter(pk=article_id).first() return render(request,'blog/article_detail.html',locals())
1、字符串转义
2、防止xss攻击
5、文章点赞
1、样式构建
html
<div id="div_digg"> <div class="diggit" onclick="votePost(9420701,'Digg')"> <span class="diggnum" id="digg_count">1</span> </div> <div class="buryit" onclick="votePost(9420701,'Bury')"> <span class="burynum" id="bury_count">0</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips">你已经推荐过了 </div> </div>
#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/img/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/img/downdown.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px; } #digg_tips{ color: red; clear: both; }
2、点赞事件绑定,
3、点赞的保存
url
# 点赞
re_path('^digg/$', views.digg, name='digg'),
view视图
多次点赞报错
4、点赞数的数据同步
5、点赞 提示,重复操作
6、点赞数的ajax更新
7、点赞的代码优化
8、代码
url
# 点赞 re_path('^digg/$', views.digg, name='digg'),
views
import json def digg(request): """点赞视图""" # print(request.POST) article_id = request.POST.get("article_id") # article_id = request.POST.get("is_up") # true is_up = json.loads(request.POST.get("is_up")) # True user_id = request.user.pk # 点赞人即为登录人 # 点赞记录以及存在 from django.http import JsonResponse # Json数据返回到前端 response = {"state":True, "msg":None, "handled":None} obj = models.ArticleUpDown.objects.filter(user_id=user_id,article_id=article_id).first() if not obj: # 创建一条点赞记录 ard = models.ArticleUpDown.objects.create(user_id=user_id,is_up=is_up,article_id=article_id) from django.db.models import F # 点赞数的保存 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 response['handled']= obj.is_up return JsonResponse(response)
点赞的模板层
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap3/css/bootstrap.css"> <script src="/static/js/jquery-3.2.1.min.js"></script> <style type="text/css"> .glyphicon-comment { vertical-align: -1px; } #div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; 125px; text-align: center; margin-top: 10px; } .diggit { float: left; 46px; height: 52px; background: url('/static/img/upup.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px; } .buryit { float: right; margin-left: 20px; 46px; height: 52px; background: url('/static/img/downdown.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px; } #digg_tips { color: red; clear: both; } </style> </head> <body> <div class="site-header"> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#"> {{ blog.title }} </a> </div> <div class="navbar-header pull-right"> <a class="navbar-brand" href="#"> 管理 </a> </div> </div> </nav> </div> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> {% load my_tags %} {% get_classification_style username %} </div> <div class="col-md-8"> {% csrf_token %} <div class="article_info"> <h3 class="text-center">{{ article_obj.title }}</h3> <div> {{ article_obj.content|safe }}</div> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">0</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips"></div> </div> </div> </div> </div> </div> </body> </html>
ajax
<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) { // 点赞 +1 if (data.state) { var val = parseInt($obj.text()); $obj.text(val+1) } else { //点赞过了 var val=data.handled?"您已经推荐过了":"您已经反对过了" $('#digg_tips').html(val) setTimeout(function () { $("#digg_tips").html("") },2000) } } }) }) </script>