django之分页算法实现(Paginator)

导入模块:from django.core.paginator import Paginator

一、Paginator的基本用法:

from django.core.paginator import Paginator
objects = ['john','paul','george','ringo','lucy','meiry','checy','wind','flow','rain']<br>
p = Paginator(objects,3)  # 3条数据为一页,实例化分页对象
print p.count  # 10 对象总共10个元素
print p.num_pages  # 4 对象可分4页
print p.page_range  # xrange(1, 5) 对象页的可迭代范围
 
page1 = p.page(1)  # 取对象的第一分页对象
print page1.object_list  # 第一分页对象的元素列表['john', 'paul', 'george']
print page1.number  # 第一分页对象的当前页值 1
 
page2 = p.page(2)  # 取对象的第二分页对象
print page2.object_list  # 第二分页对象的元素列表 ['ringo', 'lucy', 'meiry']
print page2.number  # 第二分页对象的当前页码值 2
 
print page1.has_previous()  # 第一分页对象是否有前一页 False
print page1.has_other_pages()  # 第一分页对象是否有其它页 True
 
print page2.has_previous()  # 第二分页对象是否有前一页 True
print page2.has_next()  # 第二分页对象是否有下一页 True
print page2.next_page_number()  # 第二分页对象下一页码的值 3
print page2.previous_page_number()  # 第二分页对象的上一页码值 1
print page2.start_index()  # 第二分页对象的元素开始索引 4
print page2.end_index()  # 第2分页对象的元素结束索引 6

二、分页功能实现实例:

模型:model.py

# 新闻 数据库模型
class News(models.Model):
    # 标题
    title = models.CharField(max_length=100, null=False)
    # 发布日期
    pub_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 在去模型数据的时候,按照 pub_time 字段降序排序
        ordering = ['-pub_time']

视图函数:view.py

 
 
from django.core.paginator import Paginator
from datetime import datetime
# 需要导入模型:News
# 时区转换
from django.utils.timezone import make_aware
class news_list_View(View):
def get(self, request):try:
            # request.GET.get('category',默认值):这个默认值只有在没有category这个属性的时候才会使用
            # 如果传入的是一个 "" 空字符串,也不会使用默认值
            # 所以需要 or 0 保证不为空
            # category_id = int(request.GET.get('category', 0) or 0)
            page = int(request.GET.get('p', 1))
        except:
            return HttpResponseRedirect("/cms/news_list/?p=1")
        news_all = News.objects.all()# 创建 Paginator对象
        # 参数1:一个可遍历的object对象
        # 参数2:指定多少条数据为一页
        paginator = Paginator(news_all, 10)
        # 获取分页对象
        # 参数page:int(第几页数据)
        page_obj = paginator.page(page)
        # 分页算法逻辑方法
        getdata = self.get_pagination_data(page_obj, paginator)
        content = {# 直接将分页对象 page_obj 对象发送给前端
            'page_obj': page_obj,# 获取一个可遍历的对象:range(1,paginator.count)
            # 'count_page': paginator.page_range
        }
        # 更新字典
        content.update(getdata)
        return render(request, 'cms/news_list.html', context=content)

    def get_pagination_data(self, page_boj, paginator, page_news_count=2):
        """
     分页优化
:param page_boj:当前页面对象 :param paginator: Paginator 分页对象 :param page_news_count: 左右两边显示多少页面(前端页数) “[1] [...] [5] [6] [7] [8] [9] [...] [99]” :return: """ # 获取当前页码 page_num = page_boj.number # 得到当前可以分为多少页,获取总页数 count = paginator.num_pages # 判断分页是否显示 “ ... ” left_has_more = False right_has_more = True # 返回左右显示的页码区间 range(start,end+1) 如: 1 ... 5 6 7 8 9 ... 99 # left_page_count # right_page_count      
     # 如果当前页码 >= 最大页码 -1 - page_news_count,那么就不显示 ... if page_num >= count - page_news_count - 1: right_has_more = False right_page_count = range(page_num + 1, count + 1) else: right_page_count = range(page_num + 1, page_num + 1 + page_news_count)      # if page_num >= 2 + page_news_count: left_has_more = True left_page_count = range(page_num - page_news_count, page_num) else: left_page_count = range(1, page_num) return { # 是否显示 ... 'left_has_more': left_has_more, 'right_has_more': right_has_more, # 左边应该显示的页码 'left_page_count': left_page_count, # 右边应该显示的页码 'right_page_count': right_page_count, # 最大页数 'count': count

   前端HTML模板:

   备注:使用的是 adminLTE插件完成,需要下载和导入文件如下:

    下载:adminLTE 源码

 
 
   <link rel="stylesheet" href="{% static 'adminlte/bower_components/bootstrap/dist/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'adminlte/bower_components/font-awesome/css/font-awesome.min.css' %}">
    <link rel="stylesheet" href="{% static 'adminlte/bower_components/Ionicons/css/ionicons.min.css' %}">
    <link rel="stylesheet" href="{% static 'adminlte/dist/css/AdminLTE.min.css' %}">
    <link rel="stylesheet" href=" {% static 'adminlte/dist/css/skins/_all-skins.min.css' %}">
    <link rel="stylesheet" href="{% static 'adminlte/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css' %}">

    {#    <link rel="stylesheet" href="{% static 'css_dist/common/sweetalert.min.css' %}">#}
    <link rel="stylesheet" href="http://mishengqiang.com/sweetalert/css/sweetalert.css">
    <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
    <script src="{% static 'adminlte/bower_components/jquery/dist/jquery.min.js' %}"></script>
    <script src="{% static 'adminlte/bower_components/bootstrap/dist/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'adminlte/bower_components/jquery-slimscroll/jquery.slimscroll.min.js' %}"></script>
    <script src="{% static 'adminlte/bower_components/fastclick/lib/fastclick.js' %}"></script>
    <script src="{% static 'adminlte/dist/js/adminlte.min.js' %}"></script>
    <script src="{% static 'adminlte/dist/js/demo.js' %}"></script>
<body>
  <div class="content-wrapper">
<section class="content-header">
<h1>新闻列表</h1>
</section>
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header">
<!-- form-inline:横向排列 -->

</div>
<div class="box-body">
<table class="table table-bordered">
<thead>
<tr role="row">
<td>标题</td>
<td>发布时间</td>
<td>操作</td>
</tr>
</thead>
<tbody>
{% for news in page_obj %}
<tr>
<td><a href="{% url 'news:news_detail' news_id=news.id %}">{{ news.title }}</a></td>
<td>{{ news.pub_time|time_format }}</td>
<td>
<a href="#" class="btn btn-info btn-xs">编辑</a>
<button class="btn btn-danger btn-xs delete-btn" data-news-id="{{ news.pk }}">
删除
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="box-footer">
            <!-- page_obj:当前页面的对象 -->
<lable>总页数:{{ page_obj.number }} / {{ count }}</lable>
<ul class="pagination pull-right">
              <!-- page_obj.has_previous:判断是否还有上一页 -->
{% if page_obj.has_previous %}
                 <!-- page_obj.previous_page_number:获得上一页页码 -->
<li><a href="?p={{ page_obj.previous_page_number }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0)">上一页</a></li>
{% endif %}
{% if left_has_more %}
<li><a href="?p=1">1</a></li>
<li><a href="javascript:void(0)">...</a></li>
{% endif %}

{% for left_page in left_page_count %}
<li><a href="?p={{ left_page }}">{{ left_page }}</a></li>
{% endfor %}

<li class="active"><a href="?p={{ page_obj.number }}">{{ page_obj.number }}</a>
</li>

{% for right_page in right_page_count %}
<li><a href="?p={{ right_page }}">{{ right_page }}</a></li>
{% endfor %}

{% if right_has_more %}
<li><a href="javascript:void(0)">...</a></li>
<li><a href="?p={{ count }}">{{ count }}</a></li>
{% endif %}
              <!-- page_obj.has_next:判断是否还有下一页 -->
{% if page_obj.has_next %}
                 <!-- page_obj.next_page_number:获得下一页页码 -->
<li><a href="?p={{ page_obj.next_page_number }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0)">下一页</a></li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
</section>
  </div>
</body>

 效果:

All I had was dreams and unfounded self-confidence. But everything starts here. 

最初所拥有的只是梦想,以及毫无根据的自信而已。但是,所有的一切就从这里出发。

猜你喜欢

转载自www.cnblogs.com/jingxuan-li/p/9540815.html