【博客分页功能的实现与优化】
views.py/index视图:
对首页显示的post进行分页:
# 分页开始 # 将要分页的内容全部遍历出来,这里是对Post blogs_all_list = Post.objects.all() #导入分页器,Paginator(参数1, 参数2),参数1是要分页的list,参数2是按多少分一页 paginator = Paginator(blogs_all_list, 4) # 4篇分一次页 # 获取url上 ?page= 的分页参数,获取不到,就说明是第一页,默认取1 page_num = request.GET.get('page', 1) # get_page()处理URL传来的参数,就算传来不合格参数,就自动使用默认值, # 分页完成,将变量page_of_blogs渲染到前端遍历出来 #遍历page_of_blogs.object_list,前端或后端一方 # 应该用.object_list方法获取分页器里的内容 page_of_blogs = paginator.get_page(page_num) # 现在开始对分页显示导航条做优化 # 1.(开始做分页缩显)获取当前页码,通过number方法 dangqianye = page_of_blogs.number # 2.当前页-2,当前页-1,当前页0,当前页+1,当前页+2,组成一个列表 page_range = list(range(max(dangqianye - 2, 1), dangqianye)) + list( range(dangqianye, min(dangqianye + 2, paginator.num_pages) + 1)) # 加上省略号标记 # 3.如果当前页页码范围第一页减去1大于等于2,就添加一个“...” if page_range[0] - 1 >= 2: page_range.insert(0, '....') # 4.如果最后页-当前页页码范围最后也大于等于2,就添加一个“...” if paginator.num_pages - page_range[-1] >= 2: page_range.append("....") # 5.加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) #分页优化完成,将分页导航变量page_range渲染到前端去遍历出来! content={ "post_list":page_of_blogs.object_list, #传递博客列表,分页后的列表 'page_range': page_range } return render(request,'blog/index.html',content)
注意:我们在未使用分页器分页前,post_list=Post.obj.all()是获取的全部传到前端,现在有了分页器,就应该改为传递经过分页器分后的内容去前端遍历。
index.html:
{% for post in post_list %}
<div class="blog-post" style="overflow: hidden">
<hr>
<h4 class="blog-post-title"><a href="{% url 'post_read' post.id %}">{{ post.title }}</a></h4>
<p class="blog-post-meta">发布时间:{{ post.put_in_time|date:"Y-m-d H:i"}}
作者: <a href="#">{{ post.author }}</a> 阅读量:{{ post.nums|default_if_none:0 }}</p>
<p>{{ post.context|striptags|truncatechars:200|safe}}</p>
</div><!-- /.blog-post -->
{% endfor %}
<nav aria-label="Page navigation">
<ul class="pagination">
{# 分页开始,使用.paginator.page_range方法将分页器里的页数遍历出来,并赋值给URL传递参数#}
{% for page in page_range%}
{# 如果传进来的参数里的number,是它的一个方法,可以得到当前的页码 与分页参数相等就高亮显示#}
{% if pages.number == page %}
<li class="active"><a href="?page={{ page }}">{{ page }}</a></li>
{% else %}
<li ><a href="?page={{ page }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{# 如果有下一页#}
<li >
{# 判断是否有下一页has_next#}
{% if pages.has_next %}
<a href="?page={{ page }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
{% else %}
<span aria-hidden="true">»</span>
{% endif %}
</li>
{# <li><span>共 {{ pages.paginator|length }} 页</span></li>#}
</ul>
</nav>
【代码的封装】
因为很多页面都会涉及到分页,因此我们只需要将上面的分页代码封装一下,就可以重复使用了,简单粗暴的封装一下吧:
blog/新建一个page.py,里面这样写:
from django.core.paginator import Paginator def page(Post,mun,page_num): #参数解释:post 代表要用分页的数据源,如post=Post.obj.all() #mun:表示要按多少分一页,具体数字,如:mun=4 # page_num = request.GET.get('page', 1)获取当前页码的位置,写在视图里 #视图里妖魔化元祖的方法获取返回值 # 分页开始 # 将要分页的内容全部遍历出来,这里是对Post blogs_all_list = Post # 导入分页器,Paginator(参数1, 参数2),参数1是要分页的list,参数2是按多少分一页 paginator = Paginator(blogs_all_list, mun) # 4篇分一次页 # 获取url上 ?page= 的分页参数,获取不到,就说明是第一页,默认取1 #page_num = request.GET.get('page', 1) # get_page()处理URL传来的参数,就算传来不合格参数,就自动使用默认值, # 分页完成,将变量page_of_blogs渲染到前端遍历出来 # 遍历page_of_blogs.object_list,前端或后端一方 # 应该用.object_list方法获取分页器里的内容 page_of_blogs = paginator.get_page(page_num) # 现在开始对分页显示导航条做优化 # 1.(开始做分页缩显)获取当前页码,通过number方法 dangqianye = page_of_blogs.number # 2.当前页-2,当前页-1,当前页0,当前页+1,当前页+2,组成一个列表 page_range = list(range(max(dangqianye - 2, 1), dangqianye)) + list( range(dangqianye, min(dangqianye + 2, paginator.num_pages) + 1)) # 加上省略号标记 # 3.如果当前页页码范围第一页减去1大于等于2,就添加一个“...” if page_range[0] - 1 >= 2: page_range.insert(0, '....') # 4.如果最后页-当前页页码范围最后也大于等于2,就添加一个“...” if paginator.num_pages - page_range[-1] >= 2: page_range.append("....") # 5.加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) # 分页优化完成,将分页导航变量page_range渲染到前端去遍历出来! return page_of_blogs,page_range
views.py/index视图可以这样修改了:
首页引入这个函数:
from .page import page
首页视图这样修改,获取返回作用元组的方式:
def index(request): #获取全部博客列表和从关联表里取出他们的阅读数 post_list = Post.objects.annotate(nums=Sum("read_post__read_num")) #获取全部关于我的第一条 aboutme = Aboutme.objects.first() # 分页开始 page_num = request.GET.get('page', 1) pages = page(post_list, 5, page_num) print(pages[0]) content={ "post_list":pages[0].object_list, #传递博客列表,分页后的列表 'aboutme':aboutme, 'page_range': pages[1] } return render(request,'blog/index.html',content)
这样就清爽多了,我们用这个函数继续去给分类页面分一下页吧!
0
登陆后方可评论