01: 自定义分页

目录:

1.1 自定义分页     返回顶部

  1、创建步骤

      第一步:创建views.py视图函数

      第二步:user_list.html网页文件

      第三步:utils/pagination.py文件中写Page类处理分页插件

  2、定义插件说明

      注:utils文件夹需要自己在Django项目下创建
      1、 为了防止xss攻击,网站前台收到数据默认都是字符串
      2、 可以使用mark_safe模块在前台html文件中或在后台python文件中指定将这些字符串解释成html语言

      3、 在html文件中指定后台传递的字符串是安全的:
          {{ page_str|safe }}

      4、 也可以在python后台传递前转换成安全数据
          page_str = mark_safe(page_list)

from django.shortcuts import render

from utils import pagination
#1 使用for循环模拟从数据库取出999条数据
LIST = []
for i in range(999):
    LIST.append(i)

def user_list(request):
    #2 GET可以获取url中传入的参数,用p来接收,如果并设置默认值为: 1
    current_page = request.GET.get('p',1)
    current_page = int(current_page)

    #3 实例化处理分页的Page类,并传入参数:当前页面,和共有多少条数据
    page_obj = pagination.Page(current_page,len(LIST),)

    #4 调用类方法计算,每页显示的数据,第一条数据索引和最后一条数据索引
    data = LIST[page_obj.start:page_obj.end]

    #5 在调用Page类的page_str方法时传入url路径,以便适应更多场景
    page_str = page_obj.page_str('/user_list/')
    
    return  render(request,'user_list.html',{'li':data,'page_str':page_str})
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        {#1  页面下面跳转索引样式  #}
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: #eeeeee;
            margin: 5px;}
        {#2  页面下面跳转索中当前页面a标签添加颜色  #}
        .pagination .page.active{
            background-color: brown;
            color: white;}
    </style>
</head>
<body>
    {#1 页面内容 #}
    <ul>
        {% for item in li %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>

    {#2  页面下面跳转的索引  #}
    <div class="pagination">
        {{ page_str }}
    </div>
</body>
</html>
user_list.html
from django.utils.safestring import mark_safe
class Page:
    """
        current_page: 目前显示第几页内容
        data_count: 获取的数据总共有多少条
        per_page_count:每页放多少条数据
        pager_num:每个页面下面显示索引的个数
    """
    def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
        self.current_page = current_page
        self.data_count = data_count
        self.per_page_count = per_page_count
        self.pager_num = pager_num
        print(self.current_page)
        print(self.data_count)

    @property
    def start(self):
        #每页显示的数据,第一条数据索引
        return (self.current_page - 1) * self.per_page_count

    @property
    def end(self):
        #每页显示的数据,条目的最后一条索引
        return self.current_page * self.per_page_count

    @property
    def total_count(self):
        #v是商,y是余数,这里v正好就是计算可分的页数
        v, y = divmod(self.data_count, self.per_page_count)
        if y:        #相除的余数大于0加1
            v += 1
        return v


    def page_str(self, base_url):
        page_list = []
        if self.total_count < self.pager_num:    #数据可总页数小于一页可显示的条数(total_count是类中的函数)
            start_index = 1
            end_index = self.total_count + 1     #end_index是数据总共可以分成的页数
        else:                                    #显示前面几页时增加页面,下面的页面索引不滚动增加
            if self.current_page <= (self.pager_num + 1) / 2:
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num - 1) / 2
                end_index = self.current_page + (self.pager_num + 1) / 2
                #防止页面跳转后索引大于总页面个数
                if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
                    end_index = self.total_count + 1
                    start_index = self.total_count - self.pager_num + 1

        if self.current_page == 1:
            prev = '<a class="page" href="javascript:void(0);">上一页</a>'
        else:
            prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,)
        page_list.append(prev)
        for i in range(int(start_index), int(end_index)):
            if i == self.current_page:                                        # 将当前页面的a标签变色
                temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
            else:
                temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
            page_list.append(temp)
        if self.current_page == self.total_count:
            nex = '<a class="page" href="javascript:void(0);">下一页</a>'
        else:
            nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,)
        page_list.append(nex)
        #在input中输入页码,点击GO就会跳转
        jump = """
        <input type='text'  /><a onclick ='jumpTo(this, "%s?p=");'>GO</a>
        <script>
            function jumpTo(ths,base){
                var val = ths.previousSibling.value;
                location.href = base + val;
            }
        </script>
        """ % (base_url,)
        page_list.append(jump)
        page_str = mark_safe("".join(page_list))
        return page_str
utils/pagination.py

   3、效果图

           

1.2 Django自带分页     返回顶部

  1、Django自带分页基本使用

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']

>>> p = Paginator(objects, 2)                #实例化分页实例,每页显示两条数据
>>> p.count                            #共有数据有多少条
4
>>> p.num_pages                        #总共可以分多少页
2

>>> p.page_range                        #获取分页从第几页到第几页
range(1, 3)
>>> page1 = p.page(1)                    #获取第一页
>>> page1
<Page 1 of 2>
>>> page1.object_list                    #显示第一页具体内容
['john', 'paul']
>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']

>>> page2.has_next()                    #判断是否有下一页
False
>>> page2.has_previous()                #判断是否有上一页
True
>>> page2.has_other_pages()            #判断是否有其他页
True

>>> page2.next_page_number()            #获取第二页的下一页页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number()        #获取第二页的上一页页码
1
>>> page2.start_index()                 # 获取第2页的第一条数据在所有数据中的索引
3
>>> page2.end_index()                     #获取第2页的最后一条数据在所有数据中的索引
4
Django自带分页:命令行测试功能

  2、Django自带分页实现数据分页展示 

from django.shortcuts import render

data = []
for i in range(200):
   data.append(i)

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render

def user_list(request):
    contact_list = data
    paginator = Paginator(contact_list, 10) # Show 25 contacts per page

    page = request.GET.get('page')
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:        #页数为负数(或不是整数)返回第一页
        contacts = paginator.page(1)
    except EmptyPage:
        contacts = paginator.page(paginator.num_pages)    #页数超出范围返回最后一页
    return render(request, 'user_list.html', {'contacts': contacts})
views.py
{% load tags %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        ul li{
            list-style: none;
        }
        .pagination li{
            float: left;
            margin: 5px;
        }
        .active{
            background-color: brown;
        }
    </style>
</head>
<body>
{% for contact in contacts %}
    <p>{{ contact }}</p>
{% endfor %}

<div class="pagination">
    <nav aria-label="Page navigation">
      <ul class="pagination">
        {% if contacts.has_previous %}
            <li><a href="?page={{ contacts.previous_page_number }}">上一页</a></li>
        {% endif %}

        {% for loop_counter in contacts.paginator.page_range %}
            {% render_page_ele loop_counter contacts %}
        {% endfor %}

        {% if contacts.has_next %}
            <li><a href="?page={{ contacts.next_page_number }}">下一页</a></li>
        {% endif %}
      </ul>
    </nav>
</div>
</body>
</html>
user_list.html
from django import template
from django.utils.safestring import mark_safe

register = template.Library()     #对象名register不可变
#分页
@register.simple_tag
def render_page_ele(loop_counter,query_sets):
   #query_sets.number 获取当前页
   #loop_counter循环到第几页
   if abs(query_sets.number -loop_counter) <= 3:
      ele_class = ""
      if query_sets.number == loop_counter:
         ele_class = 'active'
      ele = '''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,loop_counter,loop_counter)
      return mark_safe(ele)
   return ''
app01/templatetags/tags.py

  3、效果图

             

原文地址:https://www.cnblogs.com/xiaonq/p/8016607.html