Loading... 在上一节中,通过引入css,对网站进行美化 前端方面确实不太熟悉,就不唠叨了,用前端框架`bootstrap` 使得界面看起来想那么回事儿 这一节最终实现列表的分页  **在执行分页之前,取得的数据必须是被排序的,否则不能分页** `models.py` ```python # ... class Blog(models.Model): title = models.CharField(max_length=30) class_name = models.ForeignKey(BlogCate, on_delete=models.DO_NOTHING) content = models.TextField() author = models.ForeignKey(User, on_delete=models.DO_NOTHING) created_time = models.DateTimeField(auto_now_add=True) last_updated_time = models.DateTimeField(auto_now=True) def __str__(self): return "<Blog: %s>" % self.title # todo 如果需要分页,必须排序 class Meta(): ordering = ['-created_time'] # 安装创建的时间降序排列 # ... ``` 关于列表分页,可以使用`django.core.paginator` `paginator`这个单词翻译过来就是`分页器`,又学到一个新单词,是不是? 之前我们通过下面这行代码,获取了全部文章 ``` Blog.objects.all() ``` 对这一大团文章进行分页,让我们分页,那么我们就必须知道一页展示多少文章,是吧 编写视图函数,导入分页器库 ```python from django.shortcuts import render, get_object_or_404 from .models import Blog, BlogCate from django.core.paginator import Paginator def Blog(request): #.... blogs = Blog.objects.all() # 根据一页展示多少数量,进行分页,在实例化分页器时,就指定需要被分页的对象和一页含有文章的数量 paginator = Paginator(blogs, 3) # 这里就是一页三个数据 # ... ``` 我们实例化了分页器,我们需要的是,每一页的数据 需要哪一页,就展示哪一页的数据 所以,我们肯定得从前端那里获取到,需要访问的页数 ```python page_num = request.GET.get('page', 1) # http://127.0.0.1/blog?page=2 ``` 默认是`1`,请求过来的`page`参数,是多少所要返回的数据页码就是多少 拿到页码之后,我们就可以去对应页码中的数据了 ```python page_of_blogs = paginator.get_num(page_num) ``` ``` context['page_of_blogs'] = page_of_blogs ``` 我们现在就把数据放入到字典,然后`render`传过去 准备写模板层 现在传过来的`page_of_blogs`是一个`Page类` 这个`Page类`有一些方法,可供我们执行 ```python object_list = object_list # 获取此页全部数据 number = number # 当前页码 paginator = paginator # 分页器对象 def has_next(self): """判断是否存在下一页""" return self.number < self.paginator.num_pages def has_previous(self): """判断是否存在上一页""" return self.number > 1 def has_other_pages(self): """判断上页或者下页是否存在""" return self.has_previous() or self.has_next() def next_page_number(self): """获取下一页页码""" return self.paginator.validate_number(self.number + 1) def previous_page_number(self): """获取上一页的页码""" return self.paginator.validate_number(self.number - 1) def start_index(self): """ Return the 1-based index of the first object on this page, relative to total objects in the paginator. 获取整个分页的第一页 """ # Special case, return zero if no items. if self.paginator.count == 0: return 0 return (self.paginator.per_page * (self.number - 1)) + 1 def end_index(self): """ Return the 1-based index of the last object on this page, relative to total objects found (hits). 获取整个分页的最后一页 """ # Special case for the last page because there can be orphans. if self.number == self.paginator.num_pages: return self.paginator.count return self.number * self.paginator.per_page ``` 看了这么多,看下实际过程中,该怎么用,这样才记得牢固 毫无疑问,现在的第一目的就是获取当前页码的数据 `page_of_blogs.object_list`获取全部数据,然后进行遍历,和之前的操作大同小异 ```html {% for blog in page_of_blogs.object_list %} <div class="article"> <a href="https://www.z2blog.com/index.php/go/eyUgdXJsICdibG9nX2RldGFpbCcgYmxvZy5pZCAlfQ==" target="_blank" > <h2><ruby>blog.title }}</h2> </a> <!--truncate 缩短--> <p>{{ blog.content|truncatechars<rp> (</rp><rt>120</rt><rp>) </rp></ruby></p> <p class="blog-info"> <span class="glyphicon glyphicon-th-list"></span><a href="{% url 'blog_list' blog.class_name_id %}"><ruby>blog.class_name }}</a> <span class="glyphicon glyphicon-calendar"></span>{{ blog.created_time|date<rp> (</rp><rt>"Y-m-d G:n:s"</rt><rp>) </rp></ruby> </p> </div> {% empty %} <p>当前暂无文章</p> {% endfor %} ``` 当前页面的数据倒是全部展示出来了,但是用户可能需要往下翻页 好的,提到下一页,我们就自然想到了,下一页的页码是多少?下一页存在吗? 所以,可以用到这两个方法`has_next` `next_page_number` ```html {% if page_of_blogs.has_next %} 判断,是否存在下一页 <li> 存在,这里的链接就填写下一页的链接 <a href="https://www.z2blog.com/index.php/go/P3BhZ2U9e3sgcGFnZV9vZl9ibG9ncy5uZXh0X3BhZ2VfbnVtYmVyIH19" target="_blank" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> {% else %} 不存在,则设置class属性为disabled <li class="disabled"> <a href="https://www.z2blog.com/index.php/go/Iw==" target="_blank" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> {% endif %} ``` 现在,用户又想返回上一页,操作就和下一页的操作基本一致了,不再赘述 中间页码  这里我们去获取分页器对象的范围,然后依次遍历输出,就像python中for循环一样 ``` {% for page_num in page_of_blogs.paginator.page_range %} {% if page_of_blogs.number == page_num %} <li class="active"><a href="https://www.z2blog.com/index.php/go/P3BhZ2U9e3sgcGFnZV9udW0gfX0=" target="_blank" ><ruby>page_num }}</a></li> {% else %} <li class=""><a href="https<rp> (</rp><rt>//www.z2blog.com/index.php/go/P3BhZ2U9e3sgcGFnZV9udW0gfX0=" target="_blank" >{{ page_num</rt><rp>) </rp></ruby></a></li> {% endif %} {% endfor %} ``` 这里就还有三个方法,是`分页器对象`的方法 ``` # 获取分页范围 page_of_blogs.paginator.page_range # 获取总的分页数 page_of_blogs.paginator.num_pages # 所有分页的数据总和 page_of_blogs.paginator.count ``` Last modification:April 23rd, 2020 at 02:04 pm © 允许规范转载