泽恩小站-教程区 Help

小功能集合贴

有些功能独立的小功能 ,单独一篇文章不够分量,于是在这里集中解释了。

读者常见问题帖一样,本篇是持续更新的,想到一个写一个。

文章快捷导航

快捷导航指的是这个功能:

T42 1

点击对应按钮,页面立即跳转到另一篇文章中,省去了用户返回首页重新寻找文章的繁琐。

视图

实现本功能的关键就是要查找出发表时间与当前文章相邻的文章。为了演示简单,就粗略以id作为发表时间的排序。

在之前的搜索文章的教程中,我们已经体验过contains这种查找方法了,现在需要用到另外两种: gtlt

编写视图:

article/views.py ... # 文章详情 def article_detail(request, id): # 已有代码。取出相应的文章 article = ArticlePost.objects.get(id=id) ... # 过滤出所有的id比当前文章小的文章 pre_article = ArticlePost.objects.filter(id__lt=article.id).order_by('-id') # 过滤出id大的文章 next_article = ArticlePost.objects.filter(id__gt=article.id).order_by('id') # 取出相邻前一篇文章 if pre_article.count() > 0: pre_article = pre_article[0] else: pre_article = None # 取出相邻后一篇文章 if next_article.count() > 0: next_article = next_article[0] else: next_article = None ... # 需要传递给模板的对象 context = { ... 'pre_article': pre_article, 'next_article': next_article, }

执行逻辑如下:

  • lt过滤出所有id比当前文章小的文章

  • 对这些文章按-id进行排序

  • 取出排在首位的文章,即相邻的文章

  • 返回给模板上下文

gt的原理也是类似。

模板

模板得到上下文后,就要相应修改:

templates/detail.html ... <!-- 相邻文章导航 --> <div class="row justify-content-end"> {% if next_article %} <div class="col-auto mr-auto"> <a href="{{ next_article.get_absolute_url }}" class="btn btn-info" > {{ next_article.title }} </a> </div> {% endif %} {% if pre_article %} <div class="col-auto"> <a href="{{ pre_article.get_absolute_url }}" class="btn btn-info" > {{ pre_article.title }} </a> </div> {% endif %} </div>

代码很简单,就是按照上下文的信息,将导航按钮正确显示出来。功能就完成了。

导航的逻辑不一定非要按时间排序,也可以按照热度、文章类别甚至文字个数,这个就随便你了。

页面定位

良好的UI设计应该让用户清楚自己当前的状态。

比如我的博客就是这样的:

T42 2

可以清楚看到当前正位于【文章】-【编程】-【最近】这个页面中的。

实现方法提供给大家参考。

栏目和排序

栏目和排序都是被查询文章集合的共有属性,因此考虑在article_list()视图中把它们作为上下文传递到模板中来,类似于某种“标记”:

/views.py # 传递到模板的对象 context = { ..., 'column': column, 'order': order }

然后在模板中通过columnorder的值,控制按钮的样式:

/list.html <!-- 栏目 --> <a ... class=" ... {% if column_id == column.id %} layui-btn-warm {% else %} layui-btn-primary {% endif %} " >...</a> ... <!-- 排序 --> <a ...> {% if order == 'total_views' %} <cite>最近</cite> {% else %} 最近 {% endif %} </a>

代码中的column_id是当前页面所在的栏目, column.id是视图传递给模板的上下文。通过比对这两个值是否一致,从而决定栏目按钮的样式。

面包屑也是类似的方法,判断是否需要插入<cite>标签。

导航栏

就是我的博客顶部的“黑条”,它是所有板块的入口。

如果导航栏也采用类似上面的传递值给模板来定位,那么要求所有的app都要传递同一个"标记"到模板中。理论上可行,但是也会导致app之间耦合得太紧,个人感觉不是好的实践。

所以我采用了一种笨办法:直接在模板中读取当前的url,从而判断页面位置:

/header.html ... <li class= " ... {% if '/xxx' in request.path %} layui-this {% endif %} " > ...

这种方法有个小问题,就是如果url中恰好出现了别的板块的关键词,定位可能会显示错误。

不过对博客来说也不算什么大问题,比紧耦合的设计要好多了。

Last modified: 06 January 2025