加载中...
Django博客网站搭建--42.小功能集合贴
发表于:2020-06-18 | 分类: Django博客网站搭建
字数统计: 1.2k | 阅读时长: 4分钟 | 阅读量:

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

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

文章快捷导航

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

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

视图

实现本功能的关键就是要查找出发表时间与当前文章相邻的文章。为了演示简单,就粗略以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设计应该让用户清楚自己当前的状态。

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

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

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

例子中的样式用的LayUI,而不是Bootstrap,但是思路是相同的

读者请尝试用Bootstrap实现

栏目和排序

栏目和排序都是被查询文章集合的共有属性,因此考虑在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中恰好出现了别的板块的关键词,定位可能会显示错误。

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


持续更新中…


上一篇:
Django博客网站搭建--36.自动化测试
下一篇:
Django博客网站搭建--41.期末总结
本文目录
本文目录