Django之分页器

分页器推导

上面批量数据操作会让所有数据全部展示到一张页面上,基于上面的数据展示进行分页处理。每页展示几条

view.py

  1. from django.shortcuts import render, HttpResponse, redirect
  2. from app01 import models
  3. def index(request):
  4. data_queryset = models.Book.objects.all()
  5. current_page_num = request.GET.get('page')
  6. try:
  7. current_page_num = int(current_page_num)
  8. except Exception:
  9. current_page_num = 1
  10. if not current_page_num:
  11. current_page_num = 1
  12. # 每页展示几条数据
  13. per_page_num = 10
  14. # 起始位置
  15. start_num = (current_page_num - 1) * per_page_num
  16. # 终止位置
  17. stop_num = current_page_num * per_page_num
  18. book_queryset = data_queryset[start_num:stop_num] # 顾头不顾尾
  19. """
  20. per_page_num = 10
  21. current_page_num start_num stop_num
  22. 1 0 10
  23. 2 10 20
  24. 3 20 30
  25. per_page_num = 5
  26. current_page_num start_num stop_num
  27. 1 0 5
  28. 2 5 10
  29. 3 10 15
  30. 规律:
  31. start_num = (current_page_num-1) * per_page_num
  32. end_num = current_page_num * per_page_num
  33. """
  34. # 前端渲染的页面数量
  35. all_count = data_queryset.count()
  36. # 内置方法之 divmod()
  37. page_num, more = divmod(all_count, per_page_num)
  38. if more:
  39. page_num += 1
  40. html = ''
  41. high_light_pag = current_page_num
  42. if current_page_num < 6:
  43. current_page_num = 6
  44. for i in range(current_page_num - 5, current_page_num + 6):
  45. if high_light_pag == i:
  46. html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
  47. else:
  48. html += '<li><a href="?page=%s">%s</a></li>' % (i, i)
  49. return render(request, 'index.html', locals())

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div class="text-center">
  9. {% for book_obj in book_queryset %}
  10. <p>{{ book_obj.title }}</p>
  11. {% endfor %}
  12. <nav aria-label="Page navigation">
  13. <ul class="pagination">
  14. <li>
  15. <a href="#" aria-label="Previous">
  16. <span aria-hidden="true">&laquo;</span>
  17. </a>
  18. </li>
  19. {{ html|safe }}
  20. <li>
  21. <a href="#" aria-label="Next">
  22. <span aria-hidden="true">&raquo;</span>
  23. </a>
  24. </li>
  25. </ul>
  26. </nav>
  27. </div>
  28. </body>
  29. </html>

分页器封装模块

创建一个utils目录,写好的封装摸块的放在这个位置方便引用

my_page.py

  1. class Pagination(object):
  2. def __init__(self, current_page, all_count, per_page_num=10, pager_count=11):
  3. """
  4. 封装分页相关数据
  5. :param current_page: 当前页
  6. :param all_count: 数据库中的数据总条数
  7. :param per_page_num: 每页显示的数据条数
  8. :param pager_count: 最多显示的页码个数
  9. """
  10. try:
  11. current_page = int(current_page)
  12. except Exception as e:
  13. current_page = 1
  14. if current_page < 1:
  15. current_page = 1
  16. self.current_page = current_page
  17. self.all_count = all_count
  18. self.per_page_num = per_page_num
  19. # 总页码
  20. all_pager, tmp = divmod(all_count, per_page_num)
  21. if tmp:
  22. all_pager += 1
  23. self.all_pager = all_pager
  24. self.pager_count = pager_count
  25. self.pager_count_half = int((pager_count - 1) / 2)
  26. @property
  27. def start(self):
  28. return (self.current_page - 1) * self.per_page_num
  29. @property
  30. def end(self):
  31. return self.current_page * self.per_page_num
  32. def page_html(self):
  33. # 如果总页码 < 11个:
  34. if self.all_pager <= self.pager_count:
  35. pager_start = 1
  36. pager_end = self.all_pager + 1
  37. # 总页码 > 11
  38. else:
  39. # 当前页如果<=页面上最多显示11/2个页码
  40. if self.current_page <= self.pager_count_half:
  41. pager_start = 1
  42. pager_end = self.pager_count + 1
  43. # 当前页大于5
  44. else:
  45. # 页码翻到最后
  46. if (self.current_page + self.pager_count_half) > self.all_pager:
  47. pager_end = self.all_pager + 1
  48. pager_start = self.all_pager - self.pager_count + 1
  49. else:
  50. pager_start = self.current_page - self.pager_count_half
  51. pager_end = self.current_page + self.pager_count_half + 1
  52. page_html_list = []
  53. # 添加前面的nav和ul标签
  54. page_html_list.append('''
  55. <nav aria-label='Page navigation>'
  56. <ul class='pagination'>
  57. ''')
  58. first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
  59. page_html_list.append(first_page)
  60. if self.current_page <= 1:
  61. prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
  62. else:
  63. prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
  64. page_html_list.append(prev_page)
  65. for i in range(pager_start, pager_end):
  66. if i == self.current_page:
  67. temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
  68. else:
  69. temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
  70. page_html_list.append(temp)
  71. if self.current_page >= self.all_pager:
  72. next_page = '<li class="disabled"><a href="#">下一页</a></li>'
  73. else:
  74. next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
  75. page_html_list.append(next_page)
  76. last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
  77. page_html_list.append(last_page)
  78. # 尾部添加标签
  79. page_html_list.append('''
  80. </nav>
  81. </ul>
  82. ''')
  83. return ''.join(page_html_list)

view.py

  1. from django.shortcuts import render
  2. from app01 import models
  3. def index(request):
  4. from utils import my_page
  5. book_queryset = models.Book.objects.all()
  6. all_count = book_queryset.count()
  7. # 产生分页器对象
  8. page_obj = my_page.Pagination(current_page=request.GET.get('page'), all_count=all_count)
  9. # 产生分页数据对象
  10. page_queryset = book_queryset[page_obj.start:page_obj.end]
  11. return render(request, 'index.html', locals())

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div class="text-center">
  9. {% for book_obj in page_queryset %}
  10. <p>{{ book_obj.title }}</p>
  11. {% endfor %}
  12. {{ page_obj.page_html|safe}}
  13. </div>
  14. </body>
  15. </html>