前言
django也有自带额分页器,但是功能较少,使用起来较为繁琐。所以我们可以使用自定义非分页器。
自定义分页器的推导思路
# queryset对象是支持索引切片操作的(不支持负数索引)
book_queryset=models.Book.objects.all()
page_queryset=book_queryset[page_obj.start:page_obj.end]
# 如何获取用户访问的页数?
get请求是可以携带参数:url?page
默认显示的是第一页:current_page=request.GET.get("page",1)
"page"参数非法,则显示默认的第一页
# 设定每页的展示的记录数?
per_page_num=10
# 切片的起始位置和结束位置
start_page=(current_page-1)*10
end_page=current_page*10
# 获取展示数据的总条数
record_count=book_queryset.count() //通过queryset对象的count方法获取数据库数据的总条数
# 确定总的数据需要多少页才能展示
内置方法divmod()
base_page,is_carry=divmod(record_count,per_page_num)
# 前端模板语法没有range功能
前端代码后端书写,写完传给前端
# 针对展示页码的需要自己规划好到底展示多少个页码
一般情况下页码的个数设计都是奇数(符合审美标准) 11个页码
当前页减5
当前页加6
你可以给标签价样式从而让选中的页码高亮显示
# 针对页码小于6的情况 你需要做处理 不能再减
思路有了,那就撸起袖子写吧。
封装好的代码
"""
自定义分页器代码
"""
class Pager(object):
def __init__(self, current_page, record_count, per_page_num=8, pager_count=11):
"""
current_page:当前页
record_count:数据库中记录的总条数
per_page_num:每页最多展示的条数
pager_count: 分页器同时展示的最大数
"""
self.current_page = self.page(current_page)
self.record_count = record_count
self.per_page_num = per_page_num
self.pager_count = pager_count
self.pager_count_half = int(pager_count) // 2
@staticmethod
def page(page):
if not isinstance(page, int):
page = int(page) if page.isdigit() else 1
page = page if page > 1 else 1
return page
@property
def all_page(self):
base_page, is_carry = divmod(self.record_count, self.per_page_num)
return base_page if not is_carry else (base_page + 1)
@property
def start(self):
"""
切片操作的初始索引
"""
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
"""
切片操作的结束索引
"""
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码小于11个
if self.all_page <= self.pager_count:
pager_start = 1
pager_end = self.all_page + 1
else:
"""
总页码大于11个
"""
if self.current_page <= self.pager_count_half:
# 当前页小于等于5页
pager_start = 1
pager_end = self.pager_count + 1
else:
# 当前页大于5页
if self.current_page + self.pager_count_half > self.all_page:
pager_start = self.all_page - self.pager_count + 1
pager_end = self.all_page + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = ["""
<nav aria-label="Page navigation">
<ul class="pagination">
"""]
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page == 1:
prev_page = '<li class="disabled " ><a href="#">%s</a></li>' % ('<<',)
else:
prev_page = '<li ><a href="?page=%s">%s</a></li>' % (self.current_page - 1, '<<',)
page_html_list.append(prev_page)
for item in range(pager_start, pager_end):
if item == self.current_page:
common_page = '<li class="active " ><a href="?page=%s">%s</a></li>' % (item, item,)
else:
common_page = '<li ><a href="?page=%s" >%s</a><li>' % (item, item,)
page_html_list.append(common_page)
if self.current_page >= self.all_page:
next_page = '<li class="disabled " ><a href="#">%s</a></li>' % ('>>',)
else:
next_page = '<li ><a href="?page=%s">%s</a></li>' % (self.current_page + 1, '>>')
page_html_list.append(next_page)
last_page = '<li ><a href="?page=%s">尾页</a></li>' % (self.all_page,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append(
"""
</ul>
</nav>
"""
)
return ''.join(page_html_list)
使用
注意:
"""
当我们需要使用到非django内置的第三方功能或者组件代码的时候,一般情况下会创建一个名为utils文件夹,在该文件夹内对模块进行功能性划分,utils可以在每个应用下创建,需要具体结合实际情况。
我们自定义的分页器是基于bootstrap样式来的,所以你需要提前导入bootstrap:
(1)bootstrap 版本 v3
(2)jQuery 版本 v3
"""
└── utils
├── pager.py
└── __pycache__
└── pager.cpython-38.pyc
django后端:
class Book(View):
def get(self, request, phone):
user_obj = models.User.objects.filter(phone=phone).first()
book_list = models.Book.objects.all()
current_page = request.GET.get("page", 1)
record_count = book_list.count()
page_obj = pager.Pager(current_page, record_count, per_page_num=7, pager_count=11)
page_queryset = book_list[page_obj.start:page_obj.end]
return render(request, 'book.html',
{'user': user_obj, 'page': page_obj, 'page_queryset': page_queryset})
前端:
<div class="col-lg-6">
<div class="input-group">
<input type="text" class="form-control" placeholder="书名~">
<span class="input-group-btn">
<button class="btn btn-success" type="button">搜索~</button>
</span>
</div><!-- /input-group -->
</div>
<div class="col-lg-6 text-right">
<a href="{% url 'app01:book_add' user.phone %}" class="btn btn-success">添加书籍</a>
</div><br><br><br>
<div class="col-lg-10 col-lg-offset-1">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th class="text-center thead-style">序号</th>
<th class="text-center thead-style">书名</th>
<th class="text-center thead-style">价格(元)</th>
<th class="text-center thead-style">作者</th>
<th class="text-center thead-style">出版日期</th>
<th class="text-center thead-style">出版社</th>
<th class="text-center thead-style">操作</th>
</tr>
</thead>
<tbody>
{% for book in page_queryset %}
<tr>
<td class="text-center tbody-style">{{ page.start|add:forloop.counter }}</td>
<td>{{ book.name }}</td>
<td class="text-center">{{ book.price }}</td>
<td>
{% for author in book.authors.all %}
{% if forloop.last %}
{{ author.name }}
{% else %}
{{ author.name }}|
{% endif %}
{% endfor %}
</td>
<td class="text-right">{{ book.publish_date|date:'Y/m/d' }}</td>
<td class="text-center">{{ book.publish.name }}</td>
<td class="text-center">
<a href="{% url 'app01:book_edit' user.phone book.id %}"
class="btn btn-primary btn-xs">编辑</a>
<button class="btn btn-danger btn-xs del" delete_id="{{ book.pk }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
{{ page.page_html|safe }}
</div>
</div>