侧边栏筛选功能
"""
新技术点
1、多个url共用一个视图函数
2、当多个url公用一个视图函数的时候 应该思考着多个url能不能优化一下
"""
https://www.cnblogs.com/用户名/tag/Python/ 标签
https://www.cnblogs.com/用户名/category/850028.html 分类
https://www.cnblogs.com/用户名/archive/2016/10.html 日期
# 我们的目标格式
https://www.cnblogs.com/tiger/tag/1/ 标签
https://www.cnblogs.com/tiger/category/1 分类
https://www.cnblogs.com/tiger/archive/2020-11/ 日期
"""
username/tag/pk
username/category/pk
username/archive/year-month
"""
# url层 让筛选的页面都指向个人站点 对article进一步筛选
# 侧边栏的筛选功能
# url(r'^(?P<username>\w+)/category/(\d+)', views.site),
# url(r'^(?P<username>\w+)/tag/(\d+)', views.site),
# url(r'^(?P<username>\w+)/archive/(\w+)', views.site)
# 上面的三条url可以合并成一条
url(r'^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)/', views.site)
def site(request, username, **kwargs):
"""
:param request:
:param username:
:param kwargs: 如果该参数有值 也就意味着需要对article_list做额外的筛选操作
:return:
"""
# 先检验当前用户名对应的个人站点是否存在
user_obj = models.UserInfo.objects.filter(username=username).first()
if not user_obj:
return render(request, 'errors.html')
blog = user_obj.blog
# 查询当前个人站点下的所有文章
article_list = models.Article.objects.filter(blog=blog)
if kwargs:
# print(kwargs) # {'condition': 'tag', 'param': '1'}
condition = kwargs.get('condition')
param = kwargs.get('param')
# 判断用户到底想按照哪个条件筛选数据
if condition == 'category':
article_list = article_list.filter(category_id=param)
elif condition == 'tag':
article_list = article_list.filter(tags__id=param)
else:
year, month = param.split('-') # 2020-11 [2020, 11]
article_list = article_list.filter(create_time__year=year, create_time__month=month)
# 查询当前用户所有分类以及分类下的文章数
category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name', 'count_num', 'pk')
# < QuerySet[('tiger的分类一', 2), ('tiger的分类二', 1), ('tiger的分类三', 1)] >
# 查询当前用户所有的标签以及标签下的文章数
tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name', 'count_num', 'pk')
# <QuerySet [('tiger的标签一', 1), ('tiger的标签二', 2), ('tiger的标签三', 1)]>
# 按照年月统计所有的文章
data_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(count_num=Count('pk')).values_list('month', 'count_num')
# <QuerySet [(datetime.date(2023, 10, 1), 1), (datetime.date(2022, 8, 1), 1), (datetime.date(2022, 9, 1), 1), (datetime.date(2020, 6, 1), 1)]>
return render(request, 'site.html', locals())
# 前端展示
<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-info">
<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-danger">
<div class="panel-heading">
<h3 class="panel-title">日期归档</h3>
</div>
<div class="panel-body">
{% for data in data_list %}
# 这里需要自己设置格式 2023-10
<p><a href="/{{ username }}/archive/{{ data.0|date:'Y-m' }}">{{ data.0|date:'Y年m月' }}({{ data.1 }})</a></p>
{% endfor %}
</div>
</div>