详情页面上一篇和下一篇功能基本实现

添加了上一篇和下一篇文章功能

我不确定,上一篇指的是该文章在所有分类中的上一篇文章,还是在该文章所在分类的上一篇文章;关于下一篇同理。

于是我就按后者设计。
参考链接http://yshblog.com/blog/12
views.py中的detail方法中,加入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
prev = Post.objects.filter(pk__gt=post.pk, category=post.category).order_by('pk')
if prev.count() > 0:
prev = prev[0]
else:
prev = None
next_blog = Post.objects.filter(pk__lt=post.pk, category=post.category).order_by('-pk')
if next_post.count() > 0:
next_post = next_blog[0]
else:
next_post = None
return render(request, 'post/detail.html', context={'post': post, 'prev': prev, 'next': next_post})
...

其中__gt指的是大于,__lt是小于。

那么在detail.html中就可以使用了:

1
2
3
4
5
6
7
8
9
10
11
12
...
{% if prev %}
<li class="previous"><a href="{% url 'post:detail' prev.pk %}" title="{{ prev.title }}">上一篇:{{ prev.title|title_slice }}</a></li>
{% else %}
<li class="previous disabled"><a href="javascript:;">上一篇:没有了</a></li>
{% endif %}
{% if next %}
<li class="next"><a href="{% url 'post:detail' next.pk %}" title="{{ next.title }}">下一篇:{{ next.title|title_slice }}</a></li>
{% else %}
<li class="next disabled"><a href="javascript:;">下一篇: 没有了</a></li>
{% endif %}
...

if判断的是在没有上一篇文章,或者没有下一篇文章,即开头和结尾的情况。

你看吧,这里就用到了bootstrap的分页的样式。看起来挺不错的。

还有这个prev.title|title_slice,后面的过滤条件title_slice,是为了截取标题。如果标题太长,这个上一篇和下一篇可能会很难看。
没有采用系统默认的slice,系统默认的slice,不会在截取后的标题后面加上...,似乎就不知道你的标题是被截取过了。

当然,自定义的截取也并非多么完美,比如标题可能是中文和英文结合,而slice切片是一个中文算一个字符那样截取的,中文明显比英文要占的宽。
所以如果截取后的标题,英文多的话,就会显的很短;而中文多的话,就会显的很长。
在上一篇和下一篇显示的地方,并没有指定宽度;而首页的右边,文章列表那里,就显示出来问题了。

自定义filter

我就是在原来post_tags.py文件里面,追加了自定义的filter- title-slice。英文不好,参考这个Django翻译的中文站

1
2
3
4
5
6
7
8
9
10
11
12
13
...
# 以下是自动截取字符,并在末尾添加'...'
# 参数没必要像系统自带的slice函数那样,我只需要默认从0开始截取,不用考虑截取中间
@register.filter
def title_slice(str, arg='30'):
try:
length = int(arg)
if len(str) > length:
return str[:length] + ' ...'
else:
return str
except (ValueError, TypeError):
return str # Fail silently.

然后就可以在detail.html页面中使用了,这个过滤器有默认的参数值,如果需要指定截取的字符数,可以使用text|title_slice:'20'

PS:快要元旦了,要回家一两天,可能暂时不更新。