Django-----分页

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django-----分页相关的知识,希望对你有一定的参考价值。

一、目的

    因为往往数据库中的数据在前端页面展示出来一页肯定是不够的,而一个网页的容量就那么大,所以肯定要分页显示。


二、实施

    其实仔细想想,如果数据量小的话,直接在后台的views处理函数中分批的去获取数据就可以,比如:

models.UserInfo.objects.all()[0:10]  #UserInfo代表数据表,[0:10]表示获取第一个到第十个数据
models.UserInfo.objects.all()[0:10]   #同上


django中自带分页功能,需要导入Paginator模块,如下:

from django.core.paginator import Paginator,Page

cur_page = request.GET.get(‘page‘)   #获取用户请求中的当前页码,示例使用url--GET传值
#http://127.0.0.1:8000/index.html/?page=1
user_list = models.UserInfo.objects.all()
paginator = Paginator(user_list,10)
‘‘‘
这个paginator对象中带有如下属性:
#per_page:每页显示条目数量
#count:数据总个数
#num_pages:总页数
#page_range:总页数的索引范围,如:(1,10),(1,200)
#page:page对象
‘‘‘

posts = paginator.page(cur_page)  #如果当前页不是数字或者页码是负数的话在此加try...except
‘‘‘
# has_next              是否有下一页
# next_page_number      下一页页码
# has_previous          是否有上一页
# previous_page_number  上一页页码
# object_list           分页之后的数据列表
# number                当前页
# paginator             paginator对象
‘‘‘

return render(request,‘index.html‘,{‘posts‘:posts}  #将posts传到模板进行渲染返回页面
#模板代码如下:
<ul>
        {% for row in posts.object_list %}  #通过posts的object_list属性获取所有的数据行
            <li>{{ row.name }}</li>
        {% endfor %}
    </ul>
    <div>
        {% if posts.has_previous %}   #判断如果posts对象有上一页则渲染上一页
            <a href="/index.html?page={{ posts.previous_page_number }}">上一页</a>
        {% endif %}
         {% for num in posts.paginator.page_range %} 
             <a href="/index.html/?page={{ num }}">{{  num  }}</a>
             {% endfor %}
        {% if posts.has_next %}    #判断下一页
            <a href="/index.html?page={{ posts.next_page_number }}">下一页</a>
        {% endif %}
    </div>

注:上述django自带的分页功能会将所有页码全部显示,是有一定的局限性的,只适合有上一页下一页的网页,如果需要显示限定数目的页码的话就需要自己定制了,而且此种方法也只能在django框架中用,换作其他框架也不行。


三、自定义分页功能

#分页模块,封装成类,以后直接使用即可
class PageInfo(object):

    def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
        """

        :param current_page:当前页
        :param all_count: 数据库总行数
        :param per_page: 每页显示函数
        :base_url:url前缀
        :show_page:
        :return:
        """
        try:
            self.current_page = int(current_page) #如果页码不合理跳转到第一页
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page

        a,b = divmod(all_count,per_page)  #通过数据库数据总条数和每页显示的数据条数获取
        if b:                              #总页数(余数不为0总页数多显示1页)
            a = a +1
        self.all_pager = a
        self.show_page = show_page
        self.base_url = base_url
    def start(self):                    #数据起始位置
        return (self.current_page-1) * self.per_page

    def end(self):                       #数据结束位置
        return self.current_page * self.per_page 


    def pager(self):
        page_list = []   #用于在模板中渲染所要显示的页码

        half = int((self.show_page-1)/2)   

        # 如果数据总页数 < 11 需要显示全部页码
        if self.all_pager < self.show_page:
            begin = 1
            stop = self.all_pager + 1
        # 如果数据总页数 > 11 
        else:
            # 如果当前页 <=5,永远显示1,11
            if self.current_page <= half:
                begin = 1
                stop = self.show_page + 1
            else:
                if self.current_page + half > self.all_pager:
                    begin = self.all_pager - self.show_page + 1
                    stop = self.all_pager + 1
                else:
                    begin = self.current_page - half
                    stop = self.current_page + half + 1

        if self.current_page <= 1:
            prev = "<li><a href=‘#‘>上一页</a></li>"   #当前页为1则上一页点击不跳转
        else:
            prev = "<li><a href=‘%s?page=%s‘>上一页</a></li>" %(self.base_url,self.current_page-1,)
        page_list.append(prev)  #先将上一页标签添加到需要渲染的页码列表

        for i in range(begin,stop):
            if i == self.current_page:  #引入bootstrap,给选中页码加样式
                temp = "<li class=‘active‘><a  href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,)
            else:
                temp = "<li><a href=‘%s?page=%s‘>%s</a></li>" %(self.base_url,i,i,)
            page_list.append(temp)

        if self.current_page >= self.all_pager:   #将下一页添加在页码最后
            nex = "<li><a href=‘#‘>下一页</a></li>"
        else:
            nex = "<li><a href=‘%s?page=%s‘>下一页</a></li>" %(self.base_url,self.current_page+1,)
        page_list.append(nex)


        return ‘‘.join(page_list)  #将页码标签列表拼接成字符串返回

分页时需要做的三件事:

    1、创建处理分页数据的类

    2、根据分页数据获取数据

    3、输出分页HTML并且适当的加一些样式

以上是关于Django-----分页的主要内容,如果未能解决你的问题,请参考以下文章

django实现分页功能

Django REST框架分页的jQuery代码

modx - 当我在同上片段中使用“&documents =”参数时,分页不起作用

Django—分页器与form组件

在 Django 中为不同视图共享相同的分页代码

Django rest_framewok框架的基本组件