Django搭建个人博客:小功能集合

1954阅读 · 10评论 · 2019/01/17发布   前往评论

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

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

文章快捷导航

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

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

视图

实现本功能的关键就是要查找出发表时间与当前文章相邻的文章。为了演示简单,就粗略以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中恰好出现了别的板块的关键词,定位可能会显示错误。

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


持续更新中...






<< 日志记录 读者常见问题 >>
本文作者: 杜赛
发布时间: 2019年01月17日 - 21:24
最后更新: 2019年01月28日 - 16:20
知识共享许可协议   转载请保留原文链接及作者

登录 后回复

共有10条评论

avatar
就不上就BB 么么哒! 2

编程我爱也,摄影亦我所爱也,加个友链吧

https://frostming.com

一点建议:

1. 编辑评论和回复如果做到当前窗口就更好

2. 关于页面开放评论方便留言

6个月前 回复


avatar
杜赛 [博主] 就不上就BB 么么哒! 1

yes兄弟你的博客简洁大方啊~前往学习了。摄影也棒~

你的建议说的很对。以前没做是因为前端水平太差(现在也不怎么样),现在呢又没心思去改(就是懒)。以后一定会优化。

编程+摄影,同道中人也。

今天太晚,周末前就把你友链加上~cheeky

6个月前 回复


avatar
就不上就BB 杜赛 [博主] 么么哒! 1

简洁就是啥也没有。。。

友链已加

6个月前 回复


avatar
杜赛 [博主] 就不上就BB 么么哒! 1

同加了

正前往参观

6个月前 回复


avatar
wangfanazz 么么哒! 1

我想问一下,怎么在博客评论中添加回复功能?有没有后续文章更新

4个月前 回复


avatar
杜赛 [博主] wangfanazz 么么哒! 1

以后会讲的,教程还没写完

4个月前 回复


avatar
Python 么么哒! 1

这个文章快捷导航做好后无法正常跳转,点击后退和前进,只能停留在当前页面并刷新这个页面。我检查代码和覆盖你的代码都是一样。请问这问题出哪里?

 

4个月前 回复


avatar
杜赛 [博主] Python 么么哒! 1

用print()将视图传递的上下文打印出来看看。

检查取出的文章是否正确

3个月前 回复


avatar
spock 么么哒! 1

为了像素级模仿,已经把博主的页面代码看了好多遍,现在开始加入自己的东西了,谢谢

6天前 回复


avatar
杜赛 [博主] spock 么么哒! 1

5天前 回复