1.分页
自定义分页
class Pagination(object):
"""自定义分页(Bootstrap版)"""
def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
"""
:param current_page: 当前请求的页码
:param total_count: 总数据量
:param base_url: 请求的URL
:param per_page: 每页显示的数据量,默认值为10
:param max_show: 页面上最多显示多少个页码,默认值为11
"""
# 获取页码
self.current_page = current_page
# 定义每页显示多少条数据
self.per_page = per_page
# 计算出总页码数
total_page, more = divmod(total_count, per_page)
if more:
total_page += 1
self.total_page = total_page
# 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
self.max_show = max_show
self.half_show = max_show // 2
self.base_url = base_url
@property
def start(self):
return (self.current_page-1) * self.per_page
@property
def end(self):
return self.current_page * self.per_page
def page_html(self):
# 计算一下页面显示的页码范围
if self.total_page <= self.max_show: # 总页码数小于最大显示页码数
page_start = 1
page_end = self.total_page
elif self.current_page + self.half_show >= self.total_page: # 右边越界
page_end = self.total_page
page_start = self.total_page - self.max_show
elif self.current_page - self.half_show <= 1: # 左边越界
page_start = 1
page_end = self.max_show
else: # 正常页码区间
page_start = self.current_page - self.half_show
page_end = self.current_page + self.half_show
# 生成页面上显示的页码
page_html_list = []
page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
# 加首页
first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
page_html_list.append(first_li)
# 加上一页
if self.current_page == 1:
prev_li = '<li><a href="#"><span aria-hidden="true">«</span></a></li>'
else:
prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">«</span></a></li>'.format(
self.base_url, self.current_page - 1)
page_html_list.append(prev_li)
for i in range(page_start, page_end + 1):
if i == self.current_page:
li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
else:
li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
page_html_list.append(li_tag)
# 加下一页
if self.current_page == self.total_page:
next_li = '<li><a href="#"><span aria-hidden="true">»</span></a></li>'
else:
next_li = '<li><a href="{}?page={}"><span aria-hidden="true">»</span></a></li>'.format(
self.base_url, self.current_page + 1)
page_html_list.append(next_li)
# 加尾页
page_end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
page_html_list.append(page_end_li)
page_html_list.append('</ul></nav>')
return "".join(page_html_list)
- start:解释如下
- end:解释如下
- 根据页码获取索引起始下标
假设每页显示10条数据
页码 数据id 数据库索引 select语句
1 1-10 [0:10] show_obj = models.Books.objects.all()[0:10]
2 11-20 [10:20] show_obj = models.Books.objects.all()[10:20]
3 21-30 [20:30] show_obj = models.Books.objects.all()[20:30]
4 31-40 [30:40] show_obj = models.Books.objects.all()[30:40]
5 41-50 [40:50] show_obj = models.Books.objects.all()[40:50]
n [(n-1)*10:n*10]
使用
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edu/', include('education.urls'))
]
from django.conf.urls import url
from education import views
urlpatterns = [
url(r'^index/$', views.IndexView.as_view(), name='books')
]
from django.shortcuts import render
from django.views import View
from education import models
from utils import Pagination # 倒入分页器
class IndexView(View):
def get(self, request):
# 获取当前请求页码, 首次请求时默认返回第一页数据
try:
current_page = int(request.GET.get('page'))
except Exception as e:
current_page = 1
# 获取总数据,用于计算总页码
total_count = models.Books.objects.count()
# 调用自定义分页器
page_obj = Pagination(current_page, total_count, request.path_info, per_page=5, max_show=7)
# 每页需要显示胡数据内容
data = models.Books.objects.all()[page_obj.start:page_obj.end]
# 构建页码html
page_html = page_obj.page_html()
return render(request, "books_list.html", {"books": data, "page_html": page_html})
books_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书籍列表</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container"> // bootstrap css全局样式
<table class="table">
<thead>
<tr>
<th>序号</th>
<th>id</th>
<th>书名</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation"> // bootstrap 分页组件
<ul class="pagination">
{{ page_html| safe}}
</ul>
</nav>
</div>
</body>
</html>