BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)
BBS项目分布搭建三(个人站点时间归档补充,)
1. 个人站点时间归档
"""
settings.py设置最好更改以下:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False # 数据库时间
"""
# 在 blog.html文件中修改:
<div class="panel panel-danger">
<div class="panel-body">
时间归档
</div>
{% for date in date_list %}
<div class="panel-footer">
<a href="">{{ date.month|date:'Y-m' }}({{ date.c }})</a>
</div>
{% endfor %}
</div>
# 在views.py中修改个人站点功能:
# 7.个人站点页
def blog(request, username):
'''
验证站点是否存在
:param request:
:param username:
:return:
'''
# 验证站点的存在性 404页面
user_obj = models.UserInfo.objects.filter(username=username).first()
if not user_obj:
# 应该返回定制的404页面
return render(request, '404.html')
blog = user_obj.blog # 个人站点
# 查询当前站点的所有文章列表
article_list = models.Article.objects.filter(blog=blog).all()
'''查询当前站点下的所有标签'''
# 第一步:
tag_list = models.Tag.objects.filter(blog=blog).all()
# print(tag_list)
# 第二步:聚合查询每一个标签下的文章数量
'''
聚合查询使用关键字annotate
分组查询使用关键字aggreate
'''
from django.db.models import Count
# tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('title', 'count_num')
# tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values_list('title', 'count_num')
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num')
# print(tag_list)
'''查询当前站点下的所有分类'''
category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num')
# print(category_list)
'''把当前站点下的文章按照年月分组,并且查询分组下的文章数量'''
from django.db.models.functions import TruncMonth
# 1. 查的是添加文章的时间:年月
# 2. 查询分组之后的文章数量
# 3. month => 2021-06 => 虚拟字段
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c')
print(date_list)
return render(request, 'blog.html', locals())


2. 实现侧边栏筛选跳转功能
# 添加路由:
# 侧边栏筛选功能
# url(r'^(?P<username>\w+)/tag/(?P<param>\d+)', views.blog), # 标签
# url(r'^(?P<username>\w+)/category/(?P<param>\d+)', views.blog), # 分类
# url(r'^(?P<username>\w+)/archive/(?P<param>\w+)', views.blog), # 分类
# 以上三个地址可以合并为一个地址
url(r'^(?P<username>\w+)/(?P<conditon>tag|category|archive)/(?P<param>.*)', views.blog),
# 修改个人站点功能:
# 7.个人站点页
def blog(request, username, **kwargs):
print(123)
'''
验证站点是否存在
:param request:
:param username:
:return:
'''
# 验证站点的存在性 404页面
user_obj = models.UserInfo.objects.filter(username=username).first()
if not user_obj:
# 应该返回定制的404页面
return render(request, '404.html')
blog = user_obj.blog # 个人站点
# 查询当前站点的所有文章列表
article_list = models.Article.objects.filter(blog=blog).all()
# 侧边栏少选功能
if kwargs:
# print(kwargs) # {'conditon': 'tag', 'param': '2'}
# print(kwargs) # {'conditon': 'category', 'param': '1'}
# print(kwargs) # {'conditon': 'archive', 'param': '2022-03'}
conditon = kwargs.get('conditon')
param = kwargs.get('param')
if conditon == 'tag':
# 按照标签筛选
article_list = article_list.filter(tags__pk=param)
elif conditon == 'category':
# 按照分类进行筛选
article_list = article_list.filter(category__id=param)
else:
# 按照时间筛选
# 2022-03
year, month = param.split('-') # [2022, 03]
article_list = article_list.filter(create_time__year=year, create_time__month=month)
'''查询当前站点下的所有标签'''
# 第一步:
tag_list = models.Tag.objects.filter(blog=blog).all()
# print(tag_list)
# 第二步:聚合查询每一个标签下的文章数量
'''
聚合查询使用关键字annotate
分组查询使用关键字aggreate
'''
from django.db.models import Count
# tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('title', 'count_num')
# tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values_list('title', 'count_num')
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num', 'pk')
# print(tag_list)
'''查询当前站点下的所有分类'''
category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num', 'pk')
# print(category_list)
'''把当前站点下的文章按照年月分组,并且查询分组下的文章数量'''
from django.db.models.functions import TruncMonth
# 1. 查的是添加文章的时间:年月
# 2. 查询分组之后的文章数量
# 3. month => 2021-06 => 虚拟字段
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c')
# print(date_list)
return render(request, 'blog.html', locals())
# 修改 blog.html文件 <div class="col-md-3"> :
<div class="col-md-3">
<div class="panel panel-primary">
<div class="panel-body">
我的标签
</div>
{% for tag in tag_list %}
<div class="panel-footer">
<a href="/{{ username }}/tag/{{ tag.pk }}">{{ tag.title }}( {{ tag.count_num }})</a>
</div>
{% endfor %}
</div>
<div class="panel panel-success">
<div class="panel-body">
我的分类
</div>
{% for category in category_list %}
<div class="panel-footer">
<a href="/{{ username }}/category/{{ category.pk }}">{{ category.title }}({{ category.count_num }})</a>
</div>
{% endfor %}
</div>
<div class="panel panel-danger">
<div class="panel-body">
时间归档
</div>
{% for date in date_list %}
<div class="panel-footer">
<a href="/{{ username }}/archive/{{ date.month|date:'Y-m'}}">{{ date.month|date:'Y-m' }}({{ date.c }})</a>
</div>
{% endfor %}
</div>
</div>

3. 无限级 分类实现
# 利用新字段 pid >> parent_id 父id
给下一级的标题增加pid 就可以形成无限级分类
# 此外 红黑树数据结构 也可以实现


4. 文章详情页
# 新建公共HTML文件用于模板继承 base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="/static/layer-v3.5.1/layer/layer.js"></script>
<style>
#wrapper span {
margin-right: 10px;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">py20BBS</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
{% if request.session.username %}
<li><a href="#">{{ request.session.username }}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">更多操作 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
<li><a href="#">后台管理</a></li>
<li><a href="/logout/">退出系统</a></li>
</ul>
</li>
{% else %}
<li><a href="/register/">注册</a></li>
<li><a href="/login/">登录</a></li>
{% endif %}
</ul>
</div><!-- /.navbar-collapse -->
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="row">
<h1 class="text-center">修改密码</h1>
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<label for="old_pwd">
原密码:
</label>
<input type="text" id="old_pwd" class="form-control">
</div>
<div class="form-group">
<label for="new_pwd">
新密码:
</label>
<input type="text" id="new_pwd" class="form-control">
</div>
<div class="form-group">
<label for="re_pwd">确认密码:</label>
<input type="text" id="re_pwd" class="form-control">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary set_pwd">提交</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="panel panel-primary">
<div class="panel-body">
我的标签
</div>
{% for tag in tag_list %}
<div class="panel-footer">
<a href="/{{ username }}/tag/{{ tag.pk }}">{{ tag.title }}( {{ tag.count_num }})</a>
</div>
{% endfor %}
</div>
<div class="panel panel-success">
<div class="panel-body">
我的分类
</div>
{% for category in category_list %}
<div class="panel-footer">
<a href="/{{ username }}/category/{{ category.pk }}">{{ category.title }}({{ category.count_num }})</a>
</div>
{% endfor %}
</div>
<div class="panel panel-danger">
<div class="panel-body">
时间归档
</div>
{% for date in date_list %}
<div class="panel-footer">
<a href="/{{ username }}/archive/{{ date.month|date:'Y-m'}}">{{ date.month|date:'Y-m' }}({{ date.c }})</a>
</div>
{% endfor %}
</div>
</div>
<div class="col-md-9">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
# blog.html就可以直接继承 base.html:
{% extends 'base.html' %}
{#// 模板继承#}
{#下面为动态内容#}
{% block content %}
{% for article in article_list %}
<div class="media">
<h4 class="media-heading"><a href="">{{ article.title }}</a></h4>
<div class="media-body">
{{ article.desc }}
</div>
<div id="wrapper" class="pull-right" style="margin-top: 15px">
<span>posted</span>
<span>@</span>
<span>{{ article.create_time|date:'Y-m-d H:i' }}</span>
<span class="glyphicon glyphicon-thumbs-up">{{ article.up_num }}</span>
<span class="glyphicon glyphicon-thumbs-down">{{ article.down_num }}</span>
<span class="glyphicon glyphicon-comment">{{ article.comment_num }}</span>
</div>
</div>
{% endfor %}
{% endblock %}
# 创建文章详情页 article_detail.html:
{% extends 'base.html' %}
{% block content %}
<h1>{{ article_detail.title }}</h1>
<div class="article_content">
{{ article_detail.content|safe }}
</div>
{% endblock %}
# 添加路由 路由放在侧边筛选路由上方 避免正则匹配不到:
# 文章详情页
url(r'^(?P<username>\w+)/(?P<article_id>\d+)', views.article_detail),
# 添加文章详情页功能 views.py中:
from django.db.models import Count
# 8. 文章详情页
def article_detail(request, username, article_id):
user_obj = models.UserInfo.objects.filter(username=username).first()
if not user_obj:
return render(request, '404.html')
blog = user_obj.blog # 个人站点
# 查询文章详情数据
article_detail = models.Article.objects.filter(pk=article_id, blog=blog).first()
if not article_detail:
return render(request, '404.html')
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article')).values('title', 'count_num', 'pk')
'''查询当前站点下的所有分类'''
category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values('title', 'count_num', 'pk')
'''把当前站点下的文章按照年月分组,并且查询分组下的文章数量'''
from django.db.models.functions import TruncMonth
# 1. 查的是添加文章的时间:年月
# 2. 查询分组之后的文章数量
# 3. month => 2021-06 => 虚拟字段
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('id')).values('month', 'c')
return render(request, 'article_detail.html', locals())

BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)的更多相关文章
- BBS项目分布搭建二(个人站点相关)
BBS项目分布搭建二 1. 首页详情补充 # 在home.html文件中 body标签内补充: <div class="container-fluid"> <di ...
- BBS项目分布搭建四(点赞点踩及评论功能准备)
BBS项目分布搭建四(点赞点踩及评论功能) 1. 点赞点踩样式准备 # 在base.html文件中 head标签内 添加css模块: {% block css %} {% endblock %} # ...
- BBS项目分布搭建五(评论相关功能实现)
BBS项目分布搭建五(评论相关) 1. 根评论逻辑实现 # 在models.py文件中 修改: # 7. 评论表 parent = models.ForeignKey(to='self', null= ...
- BBS之文章详情页搭建
博客评论相关 博客文章详情页搭建 {% extends 'base.html' %} {% block css %} <style> #div_digg { float: right; m ...
- django博客项目8:文章详情页
首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容.现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样 ...
- .Net Core3.0 WebApi 项目框架搭建 三:读取appsettings.json
.Net Core3.0 WebApi 项目框架搭建:目录 appsettings.json 我们在写项目时往往会把一些经常变动的,可能会变动的参数写到配置文件.数据库中等可以存储数据且方便配置的地方 ...
- Django项目: 项目环境搭建 ---- 三、在码云平台创建项目&推送到码云上
三.在码云平台创建项目 git服务平台: 主要使用github(最主流) 国内访问速度慢 托管私有项目收费 国内一般使用码云gitee 国内访问速度快 托管私有项目免费(限制开发人数) 公司中使用gi ...
- BBS项目架构
数据库设计 用户表(用的是auth_user那张表,通过自定义表继承AbstractUser) phone 电话 avatar 头像 create_time 创建时间#外键 blog 一对一个人站点表 ...
- .Net Core3.0 WebApi 项目框架搭建:目录
一.目录 .Net Core3.0 WebApi 项目框架搭建 一:实现简单的Resful Api .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger .Net ...
随机推荐
- Swift中数据类型
Swift类型的介绍 Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等等 先了解整型和浮点型 整型 有符号 Int8 : 有符号8位整型 Int16 : 有符号16位整型 Int32 ...
- CSS样式表的书写位置
行内式(内联样式) 是通过标签的style属性来设置元素的样式,其基本语法格式如下: <标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;"&g ...
- Mysql批量删除和修改某个前缀的表
1.批量删除某个前缀的表名,首先选出这些个表. select concat( 'drop table ', table_name, ';' ) from information_schema.tabl ...
- python进阶(24)Python字典的底层原理以及字典效率
前言 问题1:python中的字典到底是有序还是无序 问题2:python中字典的效率如何 python字典底层原理 在Python 3.5以前,字典是不能保证顺序的,键值对A先插入字典,键值对B ...
- Vue 组件库:Element
目录 Element 介绍 什么是 Element ? Element 快速入门 Element 常用组件 基础布局 容器布局 表单组件 表格组件 顶部导航栏组件 侧边导航栏组件 Element 介绍 ...
- Java == 和 equals 的区别(面试描述)
== == 是一个比较运算符 既可以判断基本类型,又可以判断引用类型 如果判断基本数据类型,判断的是值是否相等 如果判断的是引用类型,判断的是地址是否相等,判断是不是同一个对象 equals equa ...
- 基于TI DSP TMS320C6455、Xilinx V5 FPGA XC5VSX95T的高速数据处理核心板
一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP TMS320C6455和一片Xilinx V5 FPGA XC5VSX95T-1FF1136i.包含1个千兆网 ...
- Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份
\(\mathcal{Description}\) Link. 给定升序序列 \(\{x_n\}\) 以及整数 \(k\),在 \(\{x_n\}\) 中选出恰 \(k\) 对 \((x_i, ...
- Netty高级应用及聊天室实战
Netty 高级应用 1. 编解码器 概念:在网络应用中,需要实现某种编解码器.将原始字节数据与自定义消息数据进行相互转换.网络中都是以字节码的形式传输的. 对Netty而言,编解码器由两部分组成:编 ...
- 硬件安全学习–RFID / Hardware security learning – RFID
RFID基础知识 RFID是什么? RFID代表近距离通讯(Radio Frequency Identification). ------------------------------------- ...