django -- 分页

简介: django -- 分页

前戏


分页是我们经常遇到的,只要有表单,数据量大的时候,都要用到分页,所以说分页是web开发里必不可少的知识点。


分页第一版


使用列表生成式来制造一些数据

user_data = [{'name':'zouzou{}'.format(i),'pwd':'abc{}'.format(i)} for i in range(1,303)]

在写个视图函数,把数据传给html文件进行渲染

def user_list(request):
    return render(request, 'user_list.html', {'data': user_data})

写一个HTML文件用于展示数据

user_list.html

{% extends 'layout.html' %}是继承母版,下面写的自己的内容。这样的效果是所有的数据都显示在了一页,肯定不是我们想要的结果。在来改写一下视图函数

def user_list(request):
    try:
        current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
        if current_page <= 0:
            current_page = 1
    except Exception as e:
        current_page = 1
    par_num = 10  # 每页显示的数量
    all_count = len(user_data)  # 总数据量
    total_num, more=divmod(all_count,par_num)  # 页码数和余数
    if more:  # 有余数,页码加1
        total_num += 1
    start = (current_page-1) * par_num  # 每页的开始值
    end = current_page * par_num  # 每页的结束值
    return render(request, 'user_list.html', {'data': user_data[start:end],
                                              "total_num":range(1, total_num+1)})

"total_num":range(1, total_num+1)} 给HTMl文件,方便渲染


修改对应的html文件

{% extends 'layout.html' %}
{% block content %}
    <table class="table table-bordered">
        <thead>
            <th>序号</th>
            <th>账号</th>
            <th>密码</th>
        </thead>
        <tbody>
        {% for user in data %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ user.name }}</td>
                <td>{{ user.pwd }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
      <nav sria-label="Page navigation">
            <ul class="pagination">
                {% for num in total_num %}
                    <li><a href="/user_list/?page={{ num }}">{{ num }}</a></li>
                {% endfor %}
            </ul>
        </nav>
{% endblock content %}

刷新页面查看效果


分页第二版(指定页码个数)


只需要更改视图函数就可以了

# 分页
def user_list(request):
    try:
        current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
        if current_page <= 0:
            current_page = 1
    except Exception as e:
        current_page = 1
    max_show = 11  # 最多显示的页码数
    half_show = max_show // 2  # 左右显示的个数
    page_start = current_page - half_show  # 开始的页码为当前页码减掉一半
    page_end = current_page + half_show  # 结束页码
    par_num = 10  # 每页显示的数量
    all_count = len(user_data)  # 总数据量
    total_num, more=divmod(all_count,par_num)  # 页码数和余数
    if more:  # 有余数,页码加1
        total_num += 1
    '''
    做判断,要不然点第一页,显示了负数,点最后一页,还往上加
    '''
    # 总页码数小于最大显示数,显示总页码数
    if total_num <= max_show:
        page_start = 1
        page_end = max_show
    else:
        # 总页码数大于最大显示数,最多显示11个
        if current_page <= half_show:
            page_start = 1
            page_end = max_show
        elif current_page+half_show >= total_num:
            page_start = total_num-max_show+1
            page_end = total_num
        else:
            page_start = current_page - half_show
            page_end = current_page + half_show
    start = (current_page-1) * par_num  # 每页的开始值
    end = current_page * par_num  # 每页的结束值
    return render(request, 'user_list.html', {'data': user_data[start:end],
                                              "total_num":range(page_start, page_end+1)})


分页第三版(增加下一页,上一页,首页,尾页)


把html里循环展示页码的代码在服务端实现

def user_list(request):
    try:
        current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
        if current_page <= 0:
            current_page = 1
    except Exception as e:
        current_page = 1
    max_show = 11  # 最多显示的页码数
    half_show = max_show // 2  # 左右显示的个数
    page_start = current_page - half_show  # 开始的页码为当前页码减掉一半
    page_end = current_page + half_show  # 结束页码
    par_num = 10  # 每页显示的数量
    all_count = len(user_data)  # 总数据量
    total_num, more=divmod(all_count,par_num)  # 页码数和余数
    if more:  # 有余数,页码加1
        total_num += 1
    '''
    做判断,要不然点第一页,显示了负数,点最后一页,还往上加
    '''
    # 总页码数小于最大显示数,显示总页码数
    if total_num <= max_show:
        page_start = 1
        page_end = max_show
    else:
        # 总页码数大于最大显示数,最多显示11个
        if current_page <= half_show:
            page_start = 1
            page_end = max_show
        elif current_page+half_show >= total_num:
            page_start = total_num-max_show+1
            page_end = total_num
        else:
            page_start = current_page - half_show
            page_end = current_page + half_show
    # 存放li标签的列表
    html_list = []
    first_li = '<li><a href="/user_list/?page=1">首页</a></li>'
    html_list.append(first_li)
    if current_page == 1:
        prev_li = '<li class="disabled"><a><<</a></li>'
    else:
        prev_li = '<li><a href="/user_list/?page={0}"><<</a></li>'.format(current_page - 1)
    html_list.append(prev_li)
    for num in range(page_start, page_end + 1):
        if current_page == num:
            li_html = '<li class="active"><a href="/user_list/?page={0}">{0}</a></li>'.format(num)
        else:
            li_html = '<li><a href="/user_list/?page={0}">{0}</a></li>'.format(num)
        html_list.append(li_html)
    if current_page == total_num:
        next_li = '<li class="disabled"><a>>></a></li>'
    else:
        next_li = '<li><a href="/user_list/?page={0}">>></a></li>'.format(current_page + 1)
    html_list.append(next_li)
    last_li = '<li><a href="/user_list/?page={}">尾页</a></li>'.format(total_num)
    html_list.append(last_li)
    html_str = mark_safe(''.join(html_list))
    start = (current_page-1) * par_num  # 每页的开始值
    end = current_page * par_num  # 每页的结束值
    return render(request, 'user_list.html', {'data': user_data[start:end],
                                              "total_num":range(page_start, page_end+1),
                                              'html_str': html_str})


最后一版


前面写的三版,分页的代码都在一个视图函数里面,如果别的页面页要用到的话,我们还要复制一遍,这样代码显的很low,我们可以在我们项目下面新建一个文件夹utils,在新建一个py文件,把我们分页的代码写到里面

"""
分页器
"""
from django.utils.safestring import mark_safe
class Pagination:
    def __init__(self, request, all_count, per_num=10, max_show=11):
        # 基本的URL
        self.base_url = request.path_info
        # 当前页码
        try:
            self.current_page = int(request.GET.get('page', 1))
            if self.current_page <= 0:
                self.current_page = 1
        except Exception as e:
            self.current_page = 1
        # 最多显示的页码数
        self.max_show = max_show
        half_show = max_show // 2
        # 每页显示的数据条数
        self.per_num = per_num
        # 总数据量
        self.all_count = all_count
        # 总页码数
        self.total_num, more = divmod(all_count, per_num)
        if more:
            self.total_num += 1
        # 总页码数小于最大显示数:显示总页码数
        if self.total_num <= max_show:
            self.page_start = 1
            self.page_end = self.total_num
        else:
            # 总页码数大于最大显示数:最多显示11个
            if self.current_page <= half_show:
                self.page_start = 1
                self.page_end = max_show
            elif self.current_page + half_show >= self.total_num:
                self.page_end = self.total_num
                self.page_start = self.total_num - max_show + 1
            else:
                self.page_start = self.current_page - half_show
                self.page_end = self.current_page + half_show
    @property
    def start(self):
        return (self.current_page - 1) * self.per_num
    @property
    def end(self):
        return self.current_page * self.per_num
    @property
    def show_li(self):
        # 存放li标签的列表
        html_list = []
        first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
        html_list.append(first_li)
        if self.current_page == 1:
            prev_li = '<li class="disabled"><a><<</a></li>'
        else:
            prev_li = '<li><a href="{1}?page={0}"><<</a></li>'.format(self.current_page - 1, self.base_url)
        html_list.append(prev_li)
        for num in range(self.page_start, self.page_end + 1):
            if self.current_page == num:
                li_html = '<li class="active"><a href="{1}?page={0}">{0}</a></li>'.format(num, self.base_url)
            else:
                li_html = '<li><a href="{1}?page={0}">{0}</a></li>'.format(num, self.base_url)
            html_list.append(li_html)
        if self.current_page == self.total_num:
            next_li = '<li class="disabled"><a>>></a></li>'
        else:
            next_li = '<li><a href="{1}?page={0}">>></a></li>'.format(self.current_page + 1, self.base_url)
        html_list.append(next_li)
        last_li = '<li><a href="{1}?page={0}">尾页</a></li>'.format(self.total_num, self.base_url)
        html_list.append(last_li)
        return mark_safe(''.join(html_list))

在视图函数里面调用

def user_list(request):
    page = Pagination(request, len(users))
    return render(request, 'user_list.html',
                  {
                      "data": users[page.start:page.end],
                      # 'total_num': range(page_start, page_end + 1)
                      'html_str': page.show_li
                  })
# 展示客户列表
def customer_list(request):
    all_customer = models.Customer.objects.all()
    page = Pagination(request, all_customer.count())
    return render(request, 'crm/customer_list.html',
                  {"all_customer": all_customer[page.start:page.end], 'pagination': page.show_li})

 


相关文章
|
6月前
|
JavaScript 数据库 Python
django实现增删改查分页接口
django实现增删改查分页接口
|
3月前
|
前端开发 关系型数据库 Python
Django入门到放弃之分页器
Django入门到放弃之分页器
|
3月前
|
安全 中间件 项目管理
Django 后端架构开发:分页器到中间件开发
Django 后端架构开发:分页器到中间件开发
43 1
|
5月前
|
JSON 搜索推荐 数据库
Django REST framework数据展示技巧:分页、过滤与搜索的实用配置与实践
Django REST framework数据展示技巧:分页、过滤与搜索的实用配置与实践
|
5月前
|
数据安全/隐私保护 Python
必知的技术知识:django自定义分页器
必知的技术知识:django自定义分页器
|
5月前
|
前端开发 数据库 Python
Python Django项目下的分页和筛选查询
在Django中实现分页功能,视图函数通过`Paginator`处理数据,每页显示10条记录。URL配置支持带参数和不带参数的分页请求。前端模板使用for循环展示分页数据,包括商品信息和状态按钮,并利用分页组件导航。筛选查询视图根据GET请求的`state`参数过滤上架或下架产品,同样实现分页功能。前端添加状态选择下拉框,分页链接携带查询参数`state`确保筛选状态在翻页时保持。
|
Python
28 Django高级- 分页
28 Django高级- 分页
39 0
【Django学习】(十二)GenericAPIView_过滤_排序_分页(上)
【Django学习】(十二)GenericAPIView_过滤_排序_分页
【Django学习】(十二)GenericAPIView_过滤_排序_分页(上)
|
数据库 Python
Django的多对多如何获取到数据并实现搜索分页
python manage.py makemigrations 应用名 python manage.py migrate 应用名 这两个命名是生成迁移文件和迁移数据库
【Django学习】(十二)GenericAPIView_过滤_排序_分页(下)
【Django学习】(十二)GenericAPIView_过滤_排序_分页(下)