from django.shortcuts import render from .models import * from django.core.paginator import Paginator, EmptyPage def page(request): # 拿到数据库queryset对象 book_queryset = Book.objects.all() # 每页10条数据,并将数据库queryset对象传入 """类实例化,paginator_set对象方法有count数据总数/num_pages总页数/page_range页码总列表(从1开始),都不需要加括号执行""" paginator_set = Paginator(book_queryset, 10) # 获取前端发送过来的page值,如果没有page参数(第一次进入页面时)或page参数为空,那么默认为1 page_num = int(request.GET.get("page", 1)) # 如果page_num值不在总页数之间,那么paginator_set.page()会报EmptyPage错 try: """类实例化,对象中包含每一页10条书籍的对象,对象方法有has_next()是否有下一页/has_previous()是否有上一页/next_page_number()下一页/previous_page_number()上一页/start_index()当前页的第一条数据在数据总数中的排序值(1开始计数)/end_index()""" current_page = paginator_set.page(page_num) except EmptyPage as e: current_page = paginator_set.page(1) # 如果总页数大于11,那么按照下面的逻辑进行判断 if paginator_set.num_pages > 11: # 当前页减去5小于1,那么页数维持在(1, 11) if page_num-5 < 1: page_range = range(1, 11) # 当前页加上5大于总页数,那么页数维持在(总页数-9, 尾页+1) elif page_num+5 > paginator_set.num_pages: page_range = range(paginator_set.num_pages-9, paginator_set.num_pages+1) # 当前页-5不小于1而且+5不大于总页数,那么页数维持在(当前页-5, 当前页+6) else: page_range = range(page_num-5, page_num+6) # 如果总页数小于11,那么页数和总页数一样,不做任何逻辑判断 else: page_range = paginator_set.page_range return render(request, "page.html", locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> <script src="/static/jQuery3.6.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-10 col-md-offset-1"> <table class="table table-bordered table-striped"> <thead> <tr> <th>序号</th> <th>书籍名称</th> <th>书籍价格</th> </tr> </thead> <tbody> {# 循环paginator_set.page()实例化的对象,可以取到每一个的书籍对象 #} {% for current in current_page %} {# 如果是每一页第一条数据, 那么序号则展示其start_index,start_index()返回值的计算方法是:(分页条数*(当前页-1))+1 #} {% if current.first %} <tr> <td>{{ current_page.start_index }}</td> <td>{{ current.title }}</td> <td>{{ current.price }}</td> </tr> {# 如果不是每一页第一条数据,那么利用start_index()方法计算的值加counter0的值,结果范围为(start_index()+1,start_index()+9) #} {% else %} <tr> <td>{{ forloop.counter0|add:current_page.start_index }}</td> <td>{{ current.title }}</td> <td>{{ current.price }}</td> </tr> {% endif %} {% endfor %} </tbody> </table> <div class="text-center"> <nav aria-label="Page navigation"> <ul class="pagination"> {# 首页按钮,固定page=1 #} <li> <a href="?page=1" aria-label="Previous"> <span aria-hidden="true">首页</span> </a> </li> {# 如果上一页还有数据,那么让其可继续点击进入上一页 #} {% if current_page.has_previous %} <li> <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {# 如果上一页没有数据了,那么不让做任何操作 #} {% else %} <li class="disabled"> <span aria-hidden="true">«</span> </li> {% endif %} {# 由后端经逻辑判断后的page_range页数列表进行循环 #} {% for page in page_range %} {# 如果循环的页码与当前查看的页码相等,那么就让其高亮显示 #} {% if page == page_num %} <li class="active"><a href="?page={{ page }}">{{ page }}</a></li> {% else %} <li><a href="?page={{ page }}">{{ page }}</a></li> {% endif %} {% endfor %} {# 如果当前页还有下一页,那么让其可以点击进入下一页 #} {% if current_page.has_next %} <li> <a href="?page={{ current_page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> {# 如果当前页没有下一页了,那么不让做任何操作 #} {% else %} <li class="disabled"> <span aria-hidden="true">»</span> </li> {% endif %} {# 跳转到尾页,让page参数直接等于总页数 #} <li> <a href="?page={{ paginator_set.num_pages }}" aria-label="Previous"> <span aria-hidden="true">尾页</span> </a> </li> </ul> </nav> </div> </div> </div> </div> </body> </html>
ORM批量插入数据方法推荐
from .models import *
book_list = [] for i in range(100): book_obj = Book( title="book_%s" % i, price=i * i, ) book_list.append(book_obj) Book.objects.bulk_create(book_list)
分页器编写思路
""" 后端: 1 先要有一个数据库queryset对象 2 实例化一个分页器对象,把数据库queryset对象和分页条数传入 3 获取到前端发送过来的页码值,页码值可能为空,设置默认值为1 4 根据前端发送过来的页码值,进行分页器对象.page(number)得到每一页的数据对象 5 前端发送过来的页码值可能有异常,所以通过try捕获错误,如果有错误将页码值设置为1 6 对页码的左、中、右展示情况进行逻辑判断 前端: 1 先遍历每一页的数据对象,展示到表格 2 序号不应按主键id进行展示,所以会有一个判断,通过每一页的数据对象的子对象.start_index与forloop.counter0相加即可成功展示 3 页码的首页尾页,上一页下一页(是否还有上一页下一页),页码高亮展示 """