Django笔记–python实现将分页功能封装成类
对于数据的表格形式呈现,庞大的数据量不可能全部放在一页中(除非数据很少)。所以基本上都需要用到分页功能。因此有必要将分页功能封装成一个类,方便使用。
pagination.py(将分页功能分装到Pagination类中)
from django.utils.safestring import mark_safe
from django.http import QueryDict
#分页器
class Pagination:
def __init__(self,request,all_count,query_params=QueryDict(),per_num=10,max_show=11): #接受一个request对象(request)与int类型的总数据量(all_count)
'''
base_url:路径
all_count: 总数据量
per_num: 每页的数据量(默认值为10)
max_show: 每页显示的页码数(默认值为11)
total_num:总页码数
current_page:当前页码
page_start:当前页面的第一个页码数
page_end:当前页面的最后一个页码数
query_params:url中的额外参数(这边指的是搜索条件)
'''
self.base_url = request.path_info #获取路径
self.max_show = max_show #获取每页显示页码数
self.per_num = per_num #获取每页的数据量
self.all_count = all_count #获取总数据量
self.query_params = query_params #url中额外的搜索参数
half_show = max_show // 2
self.total_num, more = divmod(all_count, per_num) #通过总数据量除每页数据量来获取总页码数与剩余数据量
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
if more: #如果剩余数据量不为0,则总页码数加1
self.total_num += 1
if self.total_num <= max_show: #总页码数小于最大显示页码数
self.page_start = 1
self.page_end = self.total_num
else: #总页码数大于最大显示数
if self.current_page <= half_show: #特殊情况(当前页码 - 每页显示页码数的一半 < 1)
self.page_start = 1
self.page_end = max_show
elif self.current_page >= self.total_num: #特殊情况(当前页码 + 每页显示页码数的一半 > 总页码数)
self.page_start = self.total_num - max_show + 1
self.page_end = self.total_num
else: #正常情况
self.page_start = self.current_page - half_show
self.page_end = self.current_page + half_show
def start(self):
#返回当前页码的第一个数据的索引
return (self.current_page - 1) * self.per_num
def end(self):
#返回当前页码的最后一个数据的索引
return self.current_page * self.per_num
def show_li(self):
#返回关于html的字符串(返回<li><a>标签)
'''
html_list:暂时存放html字符串的列表
first_li:关于“首页”的html字符串(直接跳转第一页的功能)
prev_li:关于“<<”的html字符串(上一页的功能)
li_html:关于页码显示的html字符串(页面跳转)
next_li:关于“>>”的html字符串(下一页的功能)
last:关于“尾页”的html字符串(直接跳转最后一页的功能)
'''
html_list = []
self.query_params['page'] = 1 #在url的二外参数中添加page
#首页
first_li = '<li><a href="{0}?{1}">首页</a></li>'.format(self.base_url,self.query_params.urlencode())
html_list.append(first_li)
#<<上一页
if self.current_page == 1:
prev_li = '<li class="disabled"><a><<</a></li>' #当上一页超过第一页,则设置不可点击disabled
else:
self.query_params['page']=self.current_page - 1 #在url的二外参数中添加page
prev_li = '<li><a href="{0}?{1}"><<</a></li>'.format(self.base_url,self.query_params.urlencode())
html_list.append(prev_li)
#显示的页码
for num in range(self.page_start, self.page_end + 1):
self.query_params['page'] = num #在url的二外参数中添加page
if self.current_page == num: #当页码为当前页码数,则设置选中状态active
li_html = '<li class="active"><a href="{0}?page={1}">{2}</a></li>'.format(self.base_url,self.query_params.urlencode(),num)
else:
li_html = '<li><a href="{0}?page={1}">{2}</a></li>'.format(self.base_url,self.query_params.urlencode(),num)
html_list.append(li_html)
#>>下一页
if self.current_page == self.total_num:
next_li = '<li class="disabled"><a>>></a></li>' #当下一页超过总页码数,则设置不可点击disabled
else:
self.query_params['page'] = self.current_page + 1 #在url的二外参数中添加page
next_li = '<li><a href="{0}?page={1}">>></a></li>'.format(self.base_url,self.query_params.urlencode())
html_list.append(next_li)
#尾页
self.query_params['page'] = self.total_num #在url的二外参数中添加page
last_li = '<li><a href="{0}?{1}">尾页</a></li>'.format(self.base_url,self.query_params.urlencode())
html_list.append(last_li)
return mark_safe(''.join(html_list)) #将列表拼接,返回字符串
后面的视图函数与html页面就列出部分,举个例子:
views.py(视图函数)
from pagination import Pagination
def customer_list(request):
all_customer = models.Customer.objects.all() #从数据库中获取数据
page = Pagination(request, all_customer.count()) #实例化对象
return render(request, 'crm/uesr_list.html', {'all_customer':all_customer[page.start():page.end()],'pagination':page.show_li()}) #返回HTML页面
user_list.html(html页面)
<table class="table table-bordered">
<thead>
<tr>
<th>序号</th>
<th>用户名</th>
<th>学号</th>
</tr>
</thead>
<tbody>
{% for user in data %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.name }}</td>
<td>{{ user.number }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div style="text-align: center">
<nav aria-label="Page navigation">
<ul class="pagination">
{{ html_str }}
</ul>
</nav>
</div>
效果图:(简单展示功能)
END!笔记就记录到此。