经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
自定义分页模板(银角大王版)
来源:cnblogs  作者:suguangti  时间:2019/6/10 13:39:26  对本文有异议

当数据库中数据有很多,我们通常会在前端页面做分页展示。

分页的数据可以在前端页面实现,也可以在后端实现分页。

后端实现分页的原理就是每次只请求一页数据。

准备工作

我们使用脚本批量创建一些测试数据(将下面的代码保存到bulk_create.py文件中放到Django项目的根目录,直接执行即可。)

  1. import os
  2. if __name__ == "__main__":
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7. bulk_obj = (models.Publisher(name='沙河第{}出版社'.format(i)) for i in range(300))
  8. models.Publisher.objects.bulk_create(bulk_obj)
测试数据创建

自定义分页

  1. def publisher_list(request):
  2. # 从URL中取当前访问的页码数
  3. try:
  4. current_page = int(request.GET.get('page'))
  5. except Exception as e:
  6. # 取不到或者页码数不是数字都默认展示第1页
  7. current_page = 1
  8. # 总数据量
  9. total_count = models.Publisher.objects.count()
  10. # 定义每页显示多少条数据
  11. per_page = 10
  12. # 计算出总页码数
  13. total_page, more = divmod(total_count, per_page)
  14. if more:
  15. total_page += 1
  16. # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
  17. max_show = 11
  18. half_show = max_show // 2
  19. # 计算一下页面显示的页码范围
  20. if total_page <= max_show: # 总页码数小于最大显示页码数
  21. page_start = 1
  22. page_end = total_page
  23. elif current_page + half_show >= total_page: # 右边越界
  24. page_end = total_page
  25. page_start = total_page - max_show
  26. elif current_page - half_show <= 1: # 左边越界
  27. page_start = 1
  28. page_end = max_show
  29. else: # 正常页码区间
  30. page_start = current_page - half_show
  31. page_end = current_page + half_show
  32. # 数据索引起始位置
  33. data_start = (current_page-1) * per_page
  34. data_end = current_page * per_page
  35. publisher_list = models.Publisher.objects.all()[data_start:data_end]
  36. # 生成页面上显示的页码
  37. page_html_list = []
  38. page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
  39. # 加首页
  40. first_li = '<li><a href="/publisher_list/?page=1">首页</a></li>'
  41. page_html_list.append(first_li)
  42. # 加上一页
  43. if current_page == 1:
  44. prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
  45. else:
  46. prev_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(current_page - 1)
  47. page_html_list.append(prev_li)
  48. for i in range(page_start, page_end + 1):
  49. if i == current_page:
  50. li_tag = '<li class="active"><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
  51. else:
  52. li_tag = '<li><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
  53. page_html_list.append(li_tag)
  54. # 加下一页
  55. if current_page == total_page:
  56. next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
  57. else:
  58. next_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(current_page + 1)
  59. page_html_list.append(next_li)
  60. # 加尾页
  61. page_end_li = '<li><a href="/publisher_list/?page={}">尾页</a></li>'.format(total_page)
  62. page_html_list.append(page_end_li)
  63. page_html_list.append('</ul></nav>')
  64. page_html = "".join(page_html_list)
  65. return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})
手撸版(内部实现原理)
  1. class Pagination(object):
  2. """自定义分页(Bootstrap版)"""
  3. def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
  4. """
  5. :param current_page: 当前请求的页码
  6. :param total_count: 总数据量
  7. :param base_url: 请求的URL
  8. :param per_page: 每页显示的数据量,默认值为10
  9. :param max_show: 页面上最多显示多少个页码,默认值为11
  10. """
  11. try:
  12. self.current_page = int(current_page)
  13. except Exception as e:
  14. # 取不到或者页码数不是数字都默认展示第1页
  15. self.current_page = 1
  16. # 定义每页显示多少条数据
  17. self.per_page = per_page
  18. # 计算出总页码数
  19. total_page, more = divmod(total_count, per_page)
  20. if more:
  21. total_page += 1
  22. self.total_page = total_page
  23. # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
  24. self.max_show = max_show
  25. self.half_show = max_show // 2
  26. self.base_url = base_url
  27. @property
  28. def start(self):
  29. return (self.current_page-1) * self.per_page
  30. @property
  31. def end(self):
  32. return self.current_page * self.per_page
  33. def page_html(self):
  34. # 计算一下页面显示的页码范围
  35. if self.total_page <= self.max_show: # 总页码数小于最大显示页码数
  36. page_start = 1
  37. page_end = self.total_page
  38. elif self.current_page + self.half_show >= self.total_page: # 右边越界
  39. page_end = self.total_page
  40. page_start = self.total_page - self.max_show
  41. elif self.current_page - self.half_show <= 1: # 左边越界
  42. page_start = 1
  43. page_end = self.max_show
  44. else: # 正常页码区间
  45. page_start = self.current_page - self.half_show
  46. page_end = self.current_page + self.half_show
  47. # 生成页面上显示的页码
  48. page_html_list = []
  49. page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
  50. # 加首页
  51. first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
  52. page_html_list.append(first_li)
  53. # 加上一页
  54. if self.current_page == 1:
  55. prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
  56. else:
  57. prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(
  58. self.base_url, self.current_page - 1)
  59. page_html_list.append(prev_li)
  60. for i in range(page_start, page_end + 1):
  61. if i == self.current_page:
  62. li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
  63. else:
  64. li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
  65. page_html_list.append(li_tag)
  66. # 加下一页
  67. if self.current_page == self.total_page:
  68. next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
  69. else:
  70. next_li = '<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(
  71. self.base_url, self.current_page + 1)
  72. page_html_list.append(next_li)
  73. # 加尾页
  74. page_end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
  75. page_html_list.append(page_end_li)
  76. page_html_list.append('</ul></nav>')
  77. return "".join(page_html_list)
模板封装建议使用版

 

  1. 后端
  2. def publisher_list(request):
  3. # 从URL中取当前访问的页码数
  4. current_page = int(request.GET.get('page'))
  5. # 比len(models.Publisher.objects.all())更高效
  6. total_count = models.Publisher.objects.count()
  7. page_obj = Pagination(current_page, total_count, request.path_info)
  8. data = models.Publisher.objects.all()[page_obj.start:page_obj.end]
  9. page_html = page_obj.page_html()
  10. return render(request, "publisher_list.html", locals())
  11. 前端
  12. 循环显示那:
  13. {% for i in publisher_list %}
  14. ....
  15. {% endfor %}
  16. {{ page_obj.page_html|safe }}
实例

Django内置分页

  1. from django.shortcuts import render
  2. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  3. L = []
  4. for i in range(999):
  5. L.append(i)
  6. def index(request):
  7. current_page = request.GET.get('p')
  8. paginator = Paginator(L, 10)
  9. # per_page: 每页显示条目数量
  10. # count: 数据总个数
  11. # num_pages:总页数
  12. # page_range:总页数的索引范围,如: (1,10),(1,200)
  13. # page: page对象
  14. try:
  15. posts = paginator.page(current_page)
  16. # has_next 是否有下一页
  17. # next_page_number 下一页页码
  18. # has_previous 是否有上一页
  19. # previous_page_number 上一页页码
  20. # object_list 分页之后的数据列表
  21. # number 当前页
  22. # paginator paginator对象
  23. except PageNotAnInteger:
  24. posts = paginator.page(1)
  25. except EmptyPage:
  26. posts = paginator.page(paginator.num_pages)
  27. return render(request, 'index.html', {'posts': posts})
Django内置分页view版
  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <ul>
  9. {% for item in posts %}
  10. <li>{{ item }}</li>
  11. {% endfor %}
  12. </ul>
  13.  
  14. <div class="pagination">
  15. <span class="step-links">
  16. {% if posts.has_previous %}
  17. <a href="?p={{ posts.previous_page_number }}">Previous</a>
  18. {% endif %}
  19. <span class="current">
  20. Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
  21. </span>
  22. {% if posts.has_next %}
  23. <a href="?p={{ posts.next_page_number }}">Next</a>
  24. {% endif %}
  25. </span>
  26.  
  27. </div>
  28. </body>
  29. </html>
Django内置分页html版

 

原文链接:http://www.cnblogs.com/suguangti/p/10993650.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号