吴先生不爱吃辣

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1,自定义分页

#utils文件夹下的page.py文件

class PagerHelper:
    #total_count总的页数,current_page当前页数,base_url页面用来分页显示的URL如http://127.0.0.1:8000/classes.html/?p=71
    #base_url为/calsses.html per_page每一页有多少条数据
    def __init__(self,total_count,current_page,base_url,per_page=10):
        self.total_count = total_count
        self.current_page = current_page
        self.base_url = base_url
        self.per_page = per_page

    @property
    def db_start(self):
        return (self.current_page -1) * self.per_page

    @property
    def db_end(self):
        return self.current_page * self.per_page
    #返回总的页数
    def total_page(self):
        v, a = divmod(self.total_count, self.per_page)
        if a != 0:
            v += 1
        return v
    #返回页码的HTML,默认是11页显示,小于11页时1-总页数,
    #当前页小于6页时总显示1-11页,当前页加5(最后一页大于总页数时)显示(总页数-11,总页数)
    def pager_str(self):

        v = self.total_page()

        pager_list = []
        if self.current_page == 1:
            pager_list.append('<a href="javascript:void(0);">上一页</a>')
        else:
            pager_list.append('<a href="%s?p=%s">上一页</a>' % (self.base_url, self.current_page - 1,))

        # 6,1:12
        # 7,2:13
        if v <= 11:
            pager_range_start = 1
            pager_range_end = v
        else:
            if self.current_page < 6:
                pager_range_start = 1
                pager_range_end = 11 + 1
            else:
                pager_range_start = self.current_page - 5
                pager_range_end = self.current_page + 5 + 1
                if pager_range_end > v:
                    pager_range_start = v - 10
                    pager_range_end = v + 1

        for i in range(pager_range_start, pager_range_end):
            if i == self.current_page:
                pager_list.append('<a class="active" href="%s?p=%s">%s</a>' % (self.base_url, i, i,))
            else:
                pager_list.append('<a href="%s?p=%s">%s</a>' % (self.base_url, i, i,))

        if self.current_page == v:
            pager_list.append('<a href="javascript:void(0);">下一页</a>')
        else:
            pager_list.append('<a href="%s?p=%s">下一页</a>' % (self.base_url, self.current_page + 1,))

        pager = "".join(pager_list)
        return pager
自定义分页

在函数中调用

#获取数据
total_count = 总的页数
current_page = 当前页数
 '/classes.html' --> 当前分页的url
5 每一页显示数据,默认是10

######
from utils.page import PagerHelper
        obj = PagerHelper(total_count, current_page, '/classes.html',5)
        pager = obj.pager_str()

        cls_list = models.Classes.objects.all()[obj.db_start:obj.db_end]

       # current_user = request.session.get('username')
        return render(request,
                      'classes.html',
                      {'username': current_user, 'cls_list': cls_list, 'str_pager': pager})
在views中使用

 2,使用paginator和bootstrap实现分页

配置分页的接口

#在utilsde page.py中配置
from django.core.paginator import Paginator
from django.conf import settings

#接受两个参数
#request
#blogs_all_list所有的博客,Blog.objects.all()
def page_paginator(request,blogs_all_list):
    paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    page_num = request.GET.get('page', 1)  # 获取url的页面参数(GET请求)
    page_of_blogs = paginator.get_page(page_num)
    # has_next              是否有下一页
    # next_page_number      下一页页码
    # has_previous          是否有上一页
    # previous_page_number  上一页页码
    # object_list           分页之后的数据列表
    # number                当前页
    # paginator             paginator对象
    currentr_page_num = page_of_blogs.number  # 获取当前页码
    # 获取当前页码前后各2页的页码范围
    page_range = list(range(max(currentr_page_num - 2, 1), currentr_page_num)) + \
                 list(range(currentr_page_num, min(currentr_page_num + 2, paginator.num_pages) + 1))
    # 加上省略页码标记
    if page_range[0] - 1 >= 2:
        page_range.insert(0, '...')
    if paginator.num_pages - page_range[-1] >= 2:
        page_range.append('...')
    # 加上首页和尾页
    if page_range[0] != 1:
        page_range.insert(0, 1)
    if page_range[-1] != paginator.num_pages:
        page_range.append(paginator.num_pages)
    # 返回当前页的博客,和[首页,前2页,.....当前页,....,后两页,尾页]
    return page_of_blogs,page_range
View Code

在views中调用接口

from utils.page import page_paginator

if request.method == 'GET':
    blogs_all_list = models.Classes.objects.all()
    page_of_blogs,page_range = page_paginator(request,blogs_all_list)
    current_user = request.session.get('username')
    return render(request,'classes.html',              {'username':current_user,'blogs':page_of_blogs.object_list,'page_of_blogs':page_of_blogs,'page_range': page_range})
View Code

在模板中使用bootstrap

#在模板temolates中的layout.html中调用
{% load staticfiles %}

<link rel="stylesheet" href="{% static 'base.css' %}">
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
    <script type="text/javascript" src="{% static 'jquery-1.12.4.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'notifications/notify.js' %}"></script>
View Code

在setting中配置每一页显示的数据

EACH_PAGE_BLOGS_NUMBER = 10

在前端html中使用

 <div class="paginator">
                    <ul class="pagination">
                        {# 上一页 #}
                        <li>
                            {% if page_of_blogs.has_previous %}
                                <a href="?p={{ page_of_blogs.previous_page_number }}" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            {% else %}
                                <span aria-hidden="true">&laquo;</span>
                            {% endif %}
                        </li>
                        {# 全部页码 #}
                        {% for page_num in page_range %}
                            {% if page_num == page_of_blogs.number %}
                                <li class="active"><span>{{ page_num }}</span></li>
                            {% else %}
                                {% if page_num == '...' %}
                                    <li><span>{{ page_num }}</span></li>
                                {% else %}
                                    <li><a href="?p={{ page_num }}">{{ page_num }}</a></li>
                                {% endif %}
                            {% endif %}
                        {% endfor %}
                        {# 下一页 #}
                        <li>
                            {% if page_of_blogs.has_next %}
                                <a href="?p={{ page_of_blogs.next_page_number }}" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            {% else %}
                                <span aria-hidden="true">&raquo;</span>
                            {% endif %}
                        </li>
                    </ul>
                    <p>
                        共有{{ page_of_blogs.paginator.count }}篇博客,
                        当前第{{ page_of_blogs.number }}页,共{{ page_of_blogs.paginator.num_pages }}页
                    </p>
                </div>
View Code

 参考gitee的地址https://gitee.com/wuzhibin112423/python_paging_management.git

3、使用django的CBV模型实现分页

views中使用的是CBV,继承了ListView类

class IndexView(ListView):
    model = Post
    template_name = 'blog/index.html'
    context_object_name = 'post_list'
    # 指定 paginate_by 属性后开启分页功能,其值代表每一页包含多少篇文章
    paginate_by = 10


#ListView默认给前端传递了以下的参数以供使用
#paginator ,即 Paginator 的实例。
#page_obj ,当前请求页面分页对象。
#is_paginated,是否已分页。只有当分页后页面超过两页时才算已分页。
#object_list,请求页面的对象列表,和 post_list 等价。所以在模板中循环文章列表时可以选 post_list ,也可以选 object_list。
views
templates/blog/index.html
 
{% if is_paginated %}
<div class="pagination-simple">
  <!-- 如果当前页还有上一页,显示一个上一页的按钮 -->
  {% if page_obj.has_previous %}
    <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
  {% endif %}
  <!-- 显示当前页面信息 -->
  <span class="current">第 {{ page_obj.number }} 页 / 共 {{ paginator.num_pages }} 页</span>
  <!-- 如果当前页还有下一页,显示一个下一页的按钮 -->
  {% if page_obj.has_next %}
    <a href="?page={{ page_obj.next_page_number }}">下一页</a>
  {% endif %}
</div>
{% endif %}
HTML

 4、使用第三方的包:django-pure-pagination来实现分页

1、先安装应用

pip install django-pure-pagination

2,注册APP

INSTALLED_APPS = [
    # ...
    'pure_pagination',  # 分页
 
    'blog.apps.BlogConfig',  # 注册 blog 应用
    'comments.apps.CommentsConfig',  # 注册 comments 应用
]
注册app

3.修改views

from pure_pagination import PaginationMixin

class IndexView(PaginationMixin, ListView):
    model = Post
    template_name = 'blog/index.html'
    context_object_name = 'post_list'
    paginate_by = 10
views

4、在settings配置分页

# django-pure-pagination 分页设置

PAGINATION_SETTINGS = {

    'PAGE_RANGE_DISPLAYED': 4, # 分页条当前页前后应该显示的总页数(两边均匀分布,因此要设置为偶数),

    'MARGIN_PAGES_DISPLAYED': 2, # 分页条开头和结尾显示的页数

    'SHOW_FIRST_PAGE_WHEN_INVALID': True, # 当请求了不存在页,显示第一页

}
settings

5、在模板中使用

{% if is_paginated %}

    {{ page_obj.render }}

{% endif %}
HTML

6、使用自定义模板覆盖预定义的模板

预定义的模板太丑,所以需要设置自定义的模板覆盖预定义的模板,django查找模板的顺序是首先在项目配置的模板根路径寻找,没有找到的话,

再去应用的templates目录下寻找。分页模板预定义的路径为 pure_pagination/pagination.html,所以我们可以在项目模板根路径下建立一个一模

一样的文件结构就可以覆盖。

/templates/pure_pagination/pagination.html

<div class="text-center pagination" style="width: 100%">
  <ul>
    {% if page_obj.has_previous %}
      <li><a href="?{{ page_obj.previous_page_number.querystring }}"
             class="prev">&lsaquo;&lsaquo; </a></li>
    {% else %}
      <li><span class="disabled prev">&lsaquo;&lsaquo; </span></li>
    {% endif %}
    {% for page in page_obj.pages %}
      {% if page %}
        {% ifequal page page_obj.number %}
          <li class="current"><a href="#">{{ page }}</a></li>
        {% else %}
          <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
        {% endifequal %}
      {% else %}
        ...
      {% endif %}
    {% endfor %}
    {% if page_obj.has_next %}
      <li><a href="?{{ page_obj.next_page_number.querystring }}" class="next"> &rsaquo;&rsaquo;</a>
      </li>
    {% else %}
      <li><span class="disabled next"> &rsaquo;&rsaquo;</span></li>
    {% endif %}
  </ul>
</div>
pagination.html

 

posted on 2020-05-03 23:34  吴先生不爱吃辣  阅读(244)  评论(0编辑  收藏  举报