如何让多条url指向相同的视图函数?
路由层:
from django.urls import path, re_path
re_path('(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)', views.site),
re_path('(?P<关键字1>\w+)/(?P<关键字2>选择1|选择2|选择3)/(?P<关键字3>.*)', views.site),
通过url不同的参数,从而传递给后端request不同的参数
视图层:
def site(request, username, **kwargs):
print(kwargs)
# 这里 kwargs 会对应的输出url传递过来的关键字参数 username condition param
if kwargs:
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:
#print(kwargs.get('condition'))
#year, month = param.split('-')
#article_list = article_list.filter(create_time__year=year, create_time__month=month)
# 将得到的不同的操作返回给模板层 前端渲染不同的页面,
return render(request, 'site.html', locals())
模板层(templates):
<a href="/{{ username }}/category/{{ category.2 }}">{{ category.0 }}({{ category.1 }})</a>
<a href="/{{ username }}/tag/{{ tag.2 }}"> {{ tag.0 }}({{ tag.1 }})</a>
<p><a href="/{{ username }}/archive/{{ date.0|date:'Y-m' }}">{{ data.0|date:'Y年m月' }}({{ data.1 }})</a></p>
# category ,tag , archive , 正好对应路由层urls中不同的关键字
完整例子
路由层(urls.py):
re_path('(?P<username>\w+)/$', views.site),
re_path('(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)', views.site),
# 第一句要加/$ 符号,结束匹配,不然会冲击掉第二条path语句,从而一直卡在第一条,
# 当然,也可以将第一条patn语句,放在第二条的位置
# 例如这样,就不需要加$符号了。
re_path('(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<param>.*)', views.site),
re_path('(?P<username>\w+)', views.site),
# 这里主要就是一个re_path 语句,匹配冲突的问题。
视图层:
def site(request, username, **kwargs):
# 先检测当前用户名对应的个人站点是否存在
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)
print(kwargs)
if kwargs:
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:
print(kwargs.get('condition'))
year, month = param.split('-')
article_list = article_list.filter(create_time__year=year, create_time__month=month)
return render(request, 'site.html', locals())
# kwargs没有数据就返回个人站点页面,有数据就返回对应的分类页。
前端:
# 按文章分类 进行分类
{% for category in category_list %}
<p>
<a href="/{{ username }}/category/{{ category.2 }}">{{ category.0 }}({{ category.1 }})</a>
</p>
{% endfor %}
# 文章标签进行分类
{% for tag in tag_list %}
<p>
<a href="/{{ username }}/tag/{{ tag.2 }}"> {{ tag.0 }}({{ tag.1 }})</a>
</p>
{% endfor %}
# 创建时间进行分类
<div class="panel-body">
{% for data in data_list %}
<p><a href="/{{ username }}/archive/{{ date.0|date:'Y-m' }}">{{ data.0|date:'Y年m月' }}({{ data.1 }})</a></p>
{% endfor %}
</div>