个人博客分页
随着个人网站上的 blog 数量不断增加, 分页功能开发提上了日程, 否则每次访问网站时进入 blog 页面, 都要同时加载几十篇 blog 的正文内容与封面图片集, 这样的体验非常糟糕(虽然只有我一个人有此困扰)。于是今天抽空着手把它实现了。
此前,在开发搜索引擎时已经实现了 pagination 功能。然而由于将其封装于搜索引擎功能模块内,因此在内部实现细节上存在疑惑。通过查阅相关资料后了解到, 传统的搜索引擎通常采用 Django 提供的 paginator 分页组件来实现 pagination 逻辑。这种实现方式大大简化了开发流程, 只需要在原有的 views 函数中添加少量代码块即可完成分页功能, 并将分页结果传递至前端展示即可完成整个 pagination 功能的搭建过程。
首先是 Django 的 paginator 类:
class Paginator(object):
def __init__(self, object_list, per_page, orphans=0,
allow_empty_first_page=True):
self.object_list = object_list
self.per_page = int(per_page)
self.orphans = int(orphans)
self.allow_empty_first_page = allow_empty_first_page
修改 views:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
def blog_list(request):
context = {}
blogs = Blog.objects.all()
blogs = blogs.order_by("-created_time")
paginator = Paginator(blogs, 6, 3) # Show 6 contacts per page, and items in last page no less than 3
page = request.GET.get('page')
try:
pnumber = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
pnumber = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
pnumber = paginator.page(paginator.num_pages)
context['max_left_item_count'] = '2' # items in item bar no longer than 5
context["blogs"] = pnumber # upload results of pagination
context["blog_types"] = BlogType.objects.all()
return render(request, 'index.html', context)
知道了函数后更新 views 实际上非常轻松。真正占用我大量时间和精力的是前端分页导航栏的开发工作。
最初我是采用 Bootstrap 的 pagination 功能进行开发的。然而,在实际应用中发现该功能存在明显不足:前端界面表现欠佳,并与博客整体风格不符。详细说明了当前系统在 pagination 功能上的不足之处。

<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
而我希望设计一个简约而又淡雅的导航栏样式。最初我的想法是尝试调整 Bootstrap 中的 pagination 模块,并非直接修改其功能属性或相关组件设置。然而这些改动并未产生预期的效果,在最终呈现的效果上也难以达到预期
我最后想到的是:由于前端设计简约美观的特点,在其组件之间也不会过于复杂。因此可以通过简单的HTML代码实现相应的功能。无需按钮元素或图形元素的支持即可完成目标功能。我们可以将独立的数字与其链接起来,并通过调整字体样式、颜色和大小后就能轻松构建出一个简洁直观的分页导航栏了。

<div class="pagination" id="fh5co-main-content" style="font-family: Courier; font-size: larger">
{% if blogs.has_previous %}
{% if blogs.number >= max_left_item_count|add:max_left_item_count %}
<a aria-hidden="true" style="color: lightpink; font-size: larger" href="?page=1">«</a>
{% endif %}
<a class="page-link" href="?page={{ blogs.previous_page_number }}">
<span aria-hidden="true" style="color: hotpink; font-size: medium;" class="glyphicon glyphicon-chevron-left"></span>
</a>
{% endif %}
{% for pg in blogs.paginator.page_range %}
{% if blogs.number == pg %}
<a class="page-link" href="?page={{ pg }}" style="color: deeppink"><u>{{ pg }}</u></a>
{% elif blogs.number|add:max_left_item_count >= pg and pg|add:max_left_item_count >= blogs.number %}
<a class="page-link" href="?page={{ pg }}" style="color: pink">{{ pg }}</a>
{% endif %}
{% endfor %}
{% if blogs.has_next %}
<a class="page-link" href="?page={{ blogs.next_page_number }}">
<span aria-hidden="true" style="color: hotpink; font-size: medium" class="glyphicon glyphicon-chevron-right"></span>
</a>
{% if blogs.paginator.num_pages > blogs.number|add:max_left_item_count %}
<a aria-hidden="true" style="color: lightpink; font-size: larger;" href="?page={{ blogs.paginator.num_pages }}">»</a>
{% endif %}
{% endif %}
</div>
任务完成并实现了后续优化工作
