当前位置: 首页 > 后端技术 > Python

第13条:分类、归档和标签页

时间:2023-03-25 20:49:12 Python

作者:HelloGitHub-追梦人本文涉及的示例代码已更新至HelloGitHub-Team仓库。侧边栏已正确显示最新文章列表、存档、分类、标签等信息。现在让我们改进归档、分类和标签功能。当用户点击存档下的某个日期、分类栏下的某个分类或标签栏下的某个标签时,会跳转到文章列表页面,并显示标签下的日期、分类或所有文章。归档页面需要显示某个归档日期下的文章列表。思路和首页显示文章列表的思路是一样的。查看主页视图的代码:blog/views.pydefindex(request):post_list=Post.objects.all()。order_by('-created_time')returnrender(request,'blog/index.html',context={'post_list':post_list})在首页视图函数中通过Post.objects.all()获取所有文章,在archive和category视图中,我们不再使用all方法获取所有文章,而是使用filter进行条件过滤。先看归档视图:blog/views.pydefarchive(request,year,month):post_list=Post.objects.filter(created_time__year=year,created_time__month=month).order_by('-created_time')returnrender(request,'blog/index.html',context={'post_list':post_list})这里使用modelmanager(objects)的filter方法来过滤文章。由于是按日期存档的,所以这里根据文章发表的年月进行筛选。具体是根据created_time的年月属性,筛选出对应年月发表的文章。请注意,created_time是一个具有年份和月份属性的Python日期对象,我们在页面边栏:使用自定义模板标签中使用了它。Python中调用属性的方式通常是created_time.year,但是因为是作为方法参数列表,django要求我们把点号换成两个下划线,即created_time__year。也像在索引视图中一样,我们对返回的文章列表进行排序。另外,由于存档页和首页的文章展示形式是一样的,所以直接复用了index.html模板。写完视图函数,配置URL:blog/urls.pyfromdjango.urlsimportpathfrom。importviewsapp_name='blog'urlpatterns=[path('',views.index,name='index'),path('posts//',views.detail,name='detail'),路径('archives///',views.archive,name='archive'),]archiveview对应的URL和detailview函数对应的URL类似。我们之前说过,django会自动从用户访问的URL中提取URL路径参数转换器规则捕获的值。然后传递给它对应的视图函数。比如用户想查看2017年3月发表的所有文章,他访问/archives/2017/3/,那么URL转换器会按照规则抓取2017和3这两个整数,然后作为参数传给归档视图函数,归档视图函数的实际调用是:archive(request,year=2017,month=3)。接下来找到inclusions文件夹下的archives模板,修改超链接的href属性,让用户点击超链接跳转到文章存档页面:inclusions/_archives.html...{%fordateindate_list%}

  • {{date.year}}年{{date.month}}月
  • {%endfor%}...这里的{%url%}用于解析视图函数blog:archive对应的urlpattern,将urlpattern中的年月替换为date.year和日期.月份。{%url%}模板标签接收到的第一个参数是解析后的视图函数的端点值。此端点值由冒号分隔的2部分组成。第一部分是application的urls.py中指定的app_name的值(起到命名空间的作用,这样即使不同app下有相同的视图函数名也不会冲突),第二部分是在路径函数值中传递的名称参数。例如,在博客应用的urls.py模块中,我们指定app_name='blog',归档视图函数的url方式为path('archives///',views.archive,name='archive'),所以对应的端点值为blog:archive。{%url%}模板标签接收到的其他参数是URL路径参数,也就是URL模式中的路径参数转换器需要捕获的值。例如归档视图功能对应的URL模式为archives///,假设date.year=2017,date.month=5,则{%url'blog:archive'date.yeardate.month%}模板标签返回值/archives/2017/5/。为什么要使用{%url%}模板标签?其实我们也可以通过设置超链接的href属性为/archives/{{date.year}}/{{date.month}}/来达到目的,但是这种写法是硬编码的。虽然blog:archive视图功能对应的URLpattern是这种形式,但是万一哪天这种pattern变了呢?如果硬编码,您需要将每次出现的/archives/{{date.year}}/{{date.month}}/更改为新模式。但是如果你使用{%url%}模板标签,你不需要做任何改变。测试一下,点击侧边栏的存档日期,跳转到存档页面,发现显示的是存档下的文章列表。分类页也写了分类页的视图函数:blog/views.pyimportmarkdownfromdjango.shortcutsimportrender,get_object_or_404#引入Category类from.modelsimportPost,Categorydefcategory(request,pk):#记得导入Category在开头classcate=get_object_or_404(Category,pk=pk)post_list=Post.objects.filter(category=cate).order_by('-created_time')returnrender(request,'blog/index.html',context={'post_list':post_list})这里我们先根据传入的pk值(即被访问的分类的id值)从数据库中获取这个分类。get_object_or_404函数与详细视图中的相同。其作用是如果用户访问的类别不存在,返回404错误页面提示用户访问不存在的资源。然后我们通过模型管理器的filter方法过滤掉该分类下的所有文章。返回的文章列表也像在主页视图中一样排序。URL配置如下:blog/urls.pyurlpatterns=[path('archives///',views.archive,name='archive'),path('categories//',views.category,name='category'),]这个分类页对应的URL模式和文章详情页对应的URL模式非常相似。具体是如何工作的大家可以自己分析分析,这里就不赘述了。修改对应模板:inclusions/_categories.html...{%forcategoryincategory_list%}
  • {{category.name}}
  • {%endfor%}...同样,{%url%}模板标签的使用方法和写存档页面时一样。现在尝试点击相应的链接,可以跳转到存档或分类页面。Tab页Tab页和category的步骤是完全一样的,所以label只要稍微修改一下category相关的代码就可以了。blog/views.pyfrom.modelsimportCategory,Post,Tagdeftag(request,pk):#记得一开始就导入Tag类t=get_object_or_404(Tag,pk=pk)post_list=Post.objects.filter(tags=t).order_by('-created_time')returnrender(request,'blog/index.html',context={'post_list':post_list})可以看出和category差不多,只是文章根据标签过滤。然后配置url:fromdjango.urlsimportpathfrom。importviewsapp_name='blog'urlpatterns=[...path('categories//',views.category,name='category'),path('tags//',视图.tag,name='tag'),]修改inclusions\_tags.html模板中的跳转链接:...{%fortagintag_list%}
  • {{tag.name}}
  • {%empty%}还没有标签!{%endfor%}...侧边栏的功能到这里就差不多完成了。欢迎关注HelloGitHub公众号获取更多开源项目的资讯和内容。《解释开源项目系列》上线——让对开源项目感兴趣的人不再害怕,让开源项目的发起者不再孤单。关注我们的文章,您将发现编程的乐趣,使用并发现参与开源项目是多么容易。欢迎联系我们投稿,让更多的人爱上开源,为开源做贡献~