【一】路由转换器
- ,slug:username 是一种路径转换器(Path Converter),它不是一个正则表达式本身,但其内部使用了正则表达式来匹配符合slug格式的字符串。Slug通常是指简洁、可读性强且不包含特殊字符的URL友好标识符,常常用于表示博客文章的标题或者用户自定义的别名等。
- 在给定的URL模式slug:username/archive/slug:year_month/中,archive是一个路径的一部分,它通常表示一个归档页面,用于展示某个时间段内的文章或内容。这里的archive可以理解为一个目录或子分类,用于存放特定年份和月份的文章。
- str:condition这个字符串可以根据你的应用逻辑来代表不同的内容或条件,比如文章ID、分类名、搜索关键词等。因为Django会将其作为URL的不同部分进行分割)。
- slug:params表示一个符合slug格式的参数,通常是由小写字母、数字和连字符组成的字符串。这个参数可以用来传递一些额外的信息,例如文章的ID、页码等。
- 例如,一个符合这个URL模式的示例路径可能是/john-doe/sports/10,其中john-doe是用户名,sports是条件,10是参数。
【一】路由地址参考
# 分类的地址跳转
# https://www.cnblogs.com/hope-ze/category/2309754.html
# http://127.0.0.1:8000/username/category/category_id
# 分类标签跳转
# https://www.cnblogs.com/hope-ze/tag/Python%E9%9D%A2%E8%AF%95%E9%A2%98/
# http://127.0.0.1:8000/username/tag/tag_id/
# 归档跳转
# https://www.cnblogs.com/hope-ze/p/archive/2024/03
# http://127.0.0.1:8000/username/archive/2024-03
【二】path 方法 + 路径转换器 写
【1】路由推到一
文章分类下的路由
path("<slug:username>/category/<int:pk>/",view)
文章标签下的路由
path("<slug:username>/tag/<int:pk>/",view)
文章归档下的路由
path("<slug:username>/archive/<slug:year_month>/",view)
到了路由视图函数中 username **kwargs 中取出 pk 或者 year_month
【2】路由推到二:将共有的部分拆出来
path("<slug:username>/") +
path("category/<int:pk>/",view)
path("tag/<int:pk>/",view)
path("archive/<slug:year_month>/",view)
到了路由视图函数中 username **kwargs 中取出 pk 或者 year_month
问题:必须存在三个路由并且每一个理由的关键字参数不一样
127.0.0.1:8000/hope/category/1/
127.0.0.1:8000/hope/tag/1/
127.0.0.1:8000/hope/archive/2023-9/
【3】优化路由
path("<slug:username>/<str:condition>/") +
path("<int:pk>/",view)
path("<int:pk>/",view)
path("<slug:year_month>/",view)
到了路由视图函数中 username condition **kwargs 中取出 pk 或者 year_month
【4】再优化
path("<slug:username>/<str:condition>/<slug:params>/")
127.0.0.1:8000/hope/category/1/
127.0.0.1:8000/hope/tag/1/
127.0.0.1:8000/hope/archive/2023-9/
到了路由视图函数中 username condition **kwargs 中取出 pk 或者 year_month
【二】用正则表达式实现上述的路由匹配规则
hope-ze \w+ \d+
re_path(r"^(?P<username>.*)/(?P<condition>category|tag|archive)/(?P<params>.*)",view)
【2】后端
def site(request, username, condition=None, params=None, *args, **kwargs):
# print(args)
print(condition) #tag 4
print(params)#2024-03
# 【一】获取到当前用户的用户名,根据指定的用户名筛选出指定的文章
# 从文章表跨到个人站点表再跨到用户表 根据用户名筛选出指定的用户数据
# blog_obj = Blog.objects.get(userinfo__username=username)
# article_data_all = Article.objects.filter(blog=blog_obj)
article_data_all = Article.objects.filter(blog__userinfo__username=username)
if condition and params:
if condition == "category":
article_data_all = Article.objects.filter(category=int(params))
elif condition == 'tag':
article_data_all = Article.objects.filter(tags=int(params))
elif condition == 'archive':
year, month = params.split("-")
print(year, month)
#聚合函数
article_data_all = Article.objects.filter(create_time__year=year, create_time__month=month)
# 判断当前路径不是我们想要的路由直接重定向回个人站点页
else:
return redirect("site", (username))
print(article_data_all)
# 获取到当前的页数
current_page = request.GET.get("page", 1)
# 获取到当前数据量的总数
all_count = article_data_all.count()
# 生成分页器对象
page_obj = Pagination(current_page=current_page, all_count=all_count, per_page_num=5)
# 对源数据进行切割
page_queryset = article_data_all[page_obj.start:page_obj.end]
return render(request, "site.html", locals())
【3】前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">我的分类</h3>
</div>
<div class="panel-body">
{% for article_category_class_obj in article_category_class_data %}
<div><a href="{% url 'article_site' username 'category' article_category_class_obj.id %}">{{ article_category_class_obj.name }} ({{ article_category_class_obj.article_num }})</a>
</div>
<hr>
{% endfor %}
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">随笔标签</h3>
</div>
<div class="panel-body">
{% for article_category_tag_obj in article_category_tag_data %}
<div><a href="{% url 'article_site' username 'tag' article_category_tag_obj.id %}">{{ article_category_tag_obj.name }} ({{ article_category_tag_obj.article_num }})</a></div>
<hr>
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">随笔档案</h3>
</div>
<div class="panel-body">
{% for article_year_month_obj in article_year_month_data %}
<div><a href="{% url 'article_site' username 'archive' article_year_month_obj.month|date:"Y-m" %}">{{ article_year_month_obj.month|date:"Y-m-d" }} ({{ article_year_month_obj.article_num }})</a>
</div>
<hr>
{% endfor %}
</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">推荐排行</h3>
</div>
<div class="panel-body">
{% for article_recommend_obj in article_recommend_data %}
<div><a href="">{{ article_recommend_obj.title }} ({{ article_recommend_obj.up_num }})</a></div>
<hr>
{% endfor %}
</div>
</div>
</body>
</html>