文章详情页内实现上一篇和下一篇文章切换

在点击进入文章的详情页,读者阅读完一篇文章后,往往会进行上一篇或者下一篇的阅读。现在我们来完善这个关键细节--实现上下篇文章切换。

先来看具体的效果图。

1.修改文章详情页 detail.html,添加上下篇文章切换页面代码:

detail.html

{% extends 'base.html' %}

{% block main %}
<article class="post post-{{ post.pk }}">
  ...
</article>

    <!-- 上下篇文章切换 开始-->
    <div>
        <div class="post-nav" style="margin-top: 5%">
            {% if has_prev %}
                <a href="{% url 'blog:detail' post_prev.pk %}" rel="prev" title="{{ post_prev.title }}" style="text-decoration: none; float: left;">
                <i class="icon-chevron-left"></i> {{ post_prev.title }}
                </a>
            {% endif %}

            {% if has_next %}
                 <a href="{% url 'blog:detail' post_next.pk %}" rel="next" title="{{ post_next.title }}" style="text-decoration: none; float: right;">
                    {{ post_next.title }} <i class="icon-chevron-right"></i>
                 </a>
            {% endif %}
        </div>
    </div>
    <!-- 上下篇文章切换 结束-->

{% endblock main %}

2.修改views.py中的视图函数detail,内容如下

blog/views.py

class PostDetailView(DetailView):
    ...

    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        post.increase_views()
        post.save()
        has_prev = False
        has_next = False
        pk_prev = pk_next = int(post.pk)
        # 假设我们最大的文章数是100
        # 当然如果不足你的需要,可适当加大
        # 但是一般不建议太大,因为会影响访问的速度
        pk_max = 100

        while not has_prev and pk_prev >= 1:
            post_prev = Post.objects.filter(pk=pk_prev - 1).first()
            if not post_prev:
                pk_prev -= 1
            else:
                has_prev = True
        while not has_next and pk_next <= pk_max:
            post_next = Post.objects.filter(pk=pk_next + 1).first()
            if not post_next:
                pk_next += 1
            else:
                has_next = True;

        return render(request, 'blog/detail.html', {
            'post': post,
            'post_prev': post_prev,
            'post_next': post_next,
            'has_prev': has_prev,
            'has_next': has_next,
        })

打开文章的详情页,就可以看到上下篇文章切换的效果了。