|
# 文章详情页
[url设计、思路]
/username/article/1
先验证url是否会被其他url顶替
文章详情页和个人站点页基本一致,所以我们用模板的继承
侧边栏的渲染需要出书数据才能渲染 并且改侧边栏在很多页面都需使用
1、哪个地方用到就拷贝需要的代码 (不推荐 优点繁琐)
2、将侧边栏制作成inclusion_tag
步骤
1、在应用下创建一个名字必须为templatetags文件夹
2、在该文件夹内创建一个任意名称的py文件
3、在该py文件内先固定书写两行代码
from django import template
register= template.Library()
[自定义过滤器-
[自定义过滤器-
[自定义========================================================================
[第一步] 创建templatetags文件夹>>tags.py文件
from django import template
from app01 import models
from django.db.models import Count
from django.db.models.functions import TruncMonth
register = template.Library()
# 自定义inclusion_tag
@register.inclusion_tag('left_menu.html')
def left_menu(username):
# 构造侧边栏需要的数据
user_obj= models.UserInfo.objects.filter(username=username).first()
blog = user_obj.blog
# 1、查询当前的用户所有分类及分类下的文章数
category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list(
'name', 'count_num', 'pk')
# print(category_list) #<QuerySet [('jason的分类一', 2), ('jason的分类二', 1), ('jason的分类三', 1)]>
# 2、查询所有用户下的标签空标签下文章数
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name',
'count_num',
'pk')
# print(tag_list) # <QuerySet [('tank的标签一', 1), ('tank的标签二', 1), ('tank的标签三', 2)]>
# 3、按照年月统计所有时间
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values(
'month').annotate(count_num=Count('pk')).values_list('month', 'count_num')
# date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(count_num=Count('pk')).values_list('month', 'count_num')
# print(date_list)
return locals()=======================================================================[第二步] 创建一个base.html,把inclusion_tag引入到内容里面去,base.html代码引用了left_menu.html[在创建的base.html中引入]
{% load mytag %}
{% left_menu username %}
[left_menu.html]<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">文章分类</h3>
</div>
<div class="panel-body">
{% for category in category_list %}
<p><a href="/{{ username }}/category/{{ category.2 }}">{{ category.0 }}({{ category.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">文章标签</h3>
</div>
<div class="panel-body">
{% for tag in tag_list %}
<p><a href="/{{ username }}/tag/{{ tag.2 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日期归档</h3>
</div>
<div class="panel-body">
{% for date in date_list %}
<p><a href="/{{ username }}/archive/{{ date.0|date:'Y-m' }}">{{ date.0|date:'Y年-m月' }}({{ date.1 }})</a></p>
{% endfor %}
</div>
</div>
[base.html代码]<body>//导航条
<nav class="navbar navbar-inverse...>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
{% load mytag %}
{% left_menu username %}
</div>
<div class="col-md-9">
{% block content %}
{% endblock %}
</div>
</div>
</div>
{% block js %}
{% endblock %}
</body>
</html>=======================================================================[后端逻辑代码def article_detail(request,article_id,username):
"""
应该需要校验username和article_id是否存在,但是我们这里先完成正确的情况
:param request:
:param article_id:
:param username:
:return:
"""
user_obj = models.UserInfo.objects.filter(username=username).first()
blog = user_obj.blog
article_obj = models.Article.objects.filter(pk=article_id,blog__userinfo__username=username).first()
if not article_obj:
return render(request,'errors.html')
return render(request,'article_detail.html',locals())============================================================================[前端article_detail.html代码{% extends 'base.html' %}
{% block css %}
<style>
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 128px;
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;}
.clear {
clear: both;
}
</style>
{% endblock %}
{% block content %}
<h1>{{ article_obj.title }}</h1>
<div class="article_content">
{{ article_obj.content|safe }}
</div>
{# 点赞点踩样式开始#}
<div>
<div id="div_digg">
<div class="diggit action" >
<span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
</div>
<div class="buryit action" >
<span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips" style="color: red">
</div>
</div>
</div>
{# 点赞点踩样式结束#}
{% endblock %}
{% block js %}
<script>
// 给所有的action类绑定事件
$('.action').click(function (){
{#alert($(this).hasClass('diggit'))#}
let isUp = $(this).hasClass('diggit');
let $div = $(this);
// 朝后端发送ajax请求
$.ajax({
url:'/up_or_down/',
type:'post',
data:{
'article_id':'{{ article_obj.pk }}',
'is_up':isUp,
'csrfmiddlewaretoken':'{{csrf_token}}',
},
success:function (args){
// 前端返回不用的点赞逻辑
if(args.code==1000){
$('#digg_tips').text(args.msg)
// 前端获取到数字加1
// 想获取到前端的数字
let oldNum = $div.children().text()
$div.children().text(Number(oldNum)+1)
}else{
$('#digg_tips').html(args.msg)
}
}
})
})
</script>
{% endblock %}
|
|
|