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 ...
随机推荐
- redis清缓存
先查询当前redis的服务是否已经启动 ps -ef|grep redis [root@guanbin-k8s-master ~]# ps -ef|grep redis redis 1557 1 0 ...
- JS 将Table内容导出到Excel(样式设计)
转载请注明来源:https://www.cnblogs.com/hookjc/ function saveAsExcel(tableID){ var tb = new TableToExcel(tab ...
- Visual Studio 下error C2471: 无法更新程序数据库
转载请注明来源:https://www.cnblogs.com/hookjc/ 解决方案:修改项目属性 右击项目 --> "属性" 1. "C/C++" ...
- 通过ANT生成MANIFEST.MF中的Class-Path属性
原文地址:http://reason2003.iteye.com/blog/1627353 之前做一个项目,主程序打包成一个jar文件,因为用到了很多第三方的lib包,所以直接通过java命令运行ja ...
- 「学习笔记」递推 & 递归
引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...
- c++ 程序编译后运行时的内存分配
程序编译后运行时的内存分配 太好的文章了,看到不得不转,转自:http://blog.sina.com.cn/s/blog_5420e0000101a0w1.html 一.编译时与运行时的内存情况 1 ...
- Cesium 加载地形数据
1.注册Cesium Ion账号,注册地址:Sign In | Cesium ion 否则,加载数据会报错{code: "InvalidCredentials", message: ...
- Django创建第一个应用App(3)
创建一个投票的应用app.现在已经创建好了一个项目,就是有了一个框架,有了框架之后就可以往框架里面填写一些自己的需求,就是放一些功能在里面即可.一个项目可以包含多个应用app,一个应用app可以属于多 ...
- python-利用xlrd模块读取excel数据,将excel数据转换成字典格式
前言 excel测试案例数据 转换成这种格式 实现代码 import os import xlrd excel_path = '..\data\\test_case.xlsx' data_path = ...
- 小牟有趣的PWN
咳咳,主要是记一下最近学二进制然后工作室里面一个一起学pwn,然后遇到的一个比较好玩的题目. 一共呢,是两个文件,这也是最近学习pwn第一次做到两个文件的题目, 如果想要源文件,这边可以加我们的工作室 ...