博客就像一本书,我们既可以在目录查询然后直接读某一章,也可以顺序一章接一章的读,但是我们目前只能从列表(不论是主页面列表还是搜索结果列表)进入特定详情页,而不能一章接一章的阅读,这显然是不方便的。这一节我们就要实现上一页/下一页的翻页功能。
只需两处修改即可实现。
获取上下页链接
第一处是修改views.py的post_detail视图逻辑:
def post_detail(request, pk):
post = get_object_or_404(Article, pk=str(pk))
post.text = markdown2.markdown(post.text, extras=['fenced-code-blocks'], )
if post.published_date == None:
return render(request, 'blog/post_detail.html', {'post': post})
else:
postsAll = Article.objects.annotate(num_comment=Count('id')).filter(
published_date__isnull=False).order_by('-published_date')
page_list = list(postsAll)
if post == page_list[-1]:
before_page = page_list[-2]
after_page = None
elif post == page_list[0]:
before_page = None
after_page = page_list[1]
else:
situ = page_list.index(post)
before_page = page_list[situ-1]
after_page = page_list[situ+1]
return render(request, 'blog/post_detail.html',
{'post': post, 'before_page': before_page, 'after_page': after_page})
对于未发布文章,该视图的逻辑不变,也就是说该功能只对已发布文章生效。对于已发布文章,先把所有已发布文章按发布时间倒序排列,之后要分三种情况:若当前文章是列表最后一个,则无下一篇,上一篇是列表倒数第二个;若当前文章是列表第一个,则无上一篇,下一篇是列表第二个;若不是上述情况,则用index方法获取当前位置,返回对应的上一个、下一个。
显示上下页链接
第二处修改是post_detail.html,把{% include "blog/duoshuo.html" %}
改为:
{% if post.published_date %}
{% if before_page %}
<div style="float: left"><a href="{% url 'post_detail' pk=before_page.pk %}">
<span class="glyphicon glyphicon-chevron-left"></span>上一篇:{{ before_page.title }}</a></div>
{% endif %}
{% if after_page %}
<div style="float: right"><a href="{% url 'post_detail' pk=after_page.pk %}">下一篇:{{ after_page.title }}<span class="glyphicon glyphicon-chevron-right"></span></a></div>
{% endif %}
{% include "blog/duoshuo.html" %}
{% endif %}
这里把上一页/下一页和多说共同归于已发布文章才有的功能。代码很好理解,就是两个链接而已。
刷新一下,点进任意一个详情页看看他指示的上下页是否正确,是否正常切换,以及第一页、最后一页的显示是否正确。
Good Luck!
这一功能的实现方法是我自己想的,如有更简单、效率更高的方法,欢迎讨论!
11.4 update:
django内建函数get_next_by_FOO与get_previous_by_FOO可以帮助我们按时间直接获取上/下一篇文章,函数的使用请看django官方文档的模型实例参考:Model instance reference
2016.10.26