使用说明:
def __init__(self, page_num, total_count, base_url, per_page_num=9, max_show=9): pass
需要传递的参数:page_num,total_count,base_url,这三个参数必须传,后面是可选,没有传递会有默认值。
page_num = request.GET.get("page") base_url = request.path_info #或者base_url=request.get_full_path() # 带参数的URL total_count = len(data)#要显示的总行数
使用传统的方式来创建一个分页系统
在视图函数中直接定义:
from django.shortcuts import render # Create your views here. data = [] for i in range(1, 302): tmp = {"id": i, "name": "alex-{}".format(i)} data.append(tmp) def user_list(request): try: page_num = int(request.GET.get("page")) # 字符串类型,所以要转成int except Exception as e: page_num = 1 # 没有传页码, 默认展示第一页 # if not page_num: # page_num = 1 # 每一页显示10条记录 per_page_num = 9 # user_list = data[0:10] 1 (1-1) *10 1*10 # user_list = data[10:20] 2 (2-1) *10 2*10 # user_list = data[20:30] 3 (n-1)*10 n*10 # 总数据个数 total_count = len(data) # 总共有多少页 total_page_num, more = divmod(total_count, per_page_num) if more: total_page_num += 1 # 如果你输入的页码数超过我的总页数,我默认返回最后一页 if page_num > total_page_num: page_num = total_page_num # 最多显示多少页码 max_show = 9 half_show = int((max_show-1)/2) # 页面上页码从哪儿开始 page_start = page_num - half_show # 页面上页码最多展示到哪一个 page_end = page_num + half_show # 如果当前页小于等于half_show, 默认从第一页展示到max_show if page_num <= half_show: page_start = 1 page_end = max_show # 如果当前页大于等于总页数-half_show if page_num >= total_page_num - half_show: page_end = total_page_num page_start = total_page_num - max_show # 生成前页码的HTML page_html_list = [] # 放置一个首页按钮 page_first_tmp = ‘<li><a href="/user_list/?page=1">首页</a></li>‘ page_html_list.append(page_first_tmp) # 加上一页按钮 if page_num - 1 <= 0: # 表示没有上一页 page_prev_tmp = ‘<li class="disabled" ><a href="#">上一页</a></li>‘ else: page_prev_tmp = ‘<li><a href="/user_list/?page={}">上一页</a></li>‘.format(page_num - 1) page_html_list.append(page_prev_tmp) for i in range(page_start, page_end+1): # 如果是当前页,就加一个active的样式 if i == page_num: tmp = ‘<li class="active"><a href="/user_list/?page={0}">{0}</a></li>‘.format(i) else: tmp = ‘<li><a href="/user_list/?page={0}">{0}</a></li>‘.format(i) page_html_list.append(tmp) # 加下一页按钮 if page_num+1 > total_page_num: page_next_tmp = ‘<li class="disabled"><a href="#">下一页</a></li>‘ else: page_next_tmp = ‘<li><a href="/user_list/?page={}">下一页</a></li>‘.format(page_num+1) page_html_list.append(page_next_tmp) # 添加一个尾页 page_last_tmp = ‘<li><a href="/user_list/?page={}">尾页</a></li>‘.format(total_page_num) page_html_list.append(page_last_tmp) page_html = "".join(page_html_list) # 去数据库取数据 start = (page_num - 1) * per_page_num end = page_num * per_page_num user_list = data[start:end] return render(request, "user_list.html", {"user_list": user_list, "page_html": page_html})
在这里面,data可以换成实际存在的数据库取出来的数据。
这样就能在前端页面中访问了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> </head> <body> <div class="container"></div> <div class="col-md-8 col-md-offset-2"> <table class="table table-bordered table-hover"> <thead> <tr class="info"> <th>id</th> <th>姓名</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ user.name }}</td> </tr> {% endfor %} </tbody> </table> <div class="text-right"> <ul class="pagination"> {# 直接将结果在前端封装#} {# {% for i in total_page_num %}#} {# <li><a href="/user_list/?page={{ i }}">{{ i }}</a></li>#} {# {% endfor %}#} {# 这样写不太好,所以在后面跟你拼接#} {# safe是防止xss攻击,默认防止其它外来代码改变页面#} {{ page_html|safe }} </ul> </div> </div> </div> </body> </html>
其实这样定义是把它写死了,有更加灵活的写法,我们可以将这个分页系统封装成一个模块,
需要打印数据的时候,只需要传入固定的参数,就可在前端页面展示了,就像这样:
#定义一个视图函数 def user_list(request): page_num = request.GET.get("page") #获取当前请求的页面的路径,也就是url path = request.path_info # request.get_full_path() # 带参数的URL #直接调用函数了 from tools.mypage import MyPage #传入固定的参数 page = MyPage(page_num, len(data), path) #将结果封装,这样页面看起来更加舒服。 page_html = page.page_html() return render(request, "user_list.html", {"user_list": data[page.start:page.end], "page_html": page_html}
可以看到这样调用的方式可以大大提高代码的重复性。
下面展示封装的函数:
class MyPage(object): def __init__(self, page_num, total_count, base_url, per_page_num=9, max_show=9): """ :param page_num: 当前页 :param total_count: 数据总个数 :param base_url: 分页页码跳转的URL :param per_page_num: 每一页显示多少条数据 :param max_show: 页面上最多显示多少页码 """ # 实例化时传进来的参数 try: self.page_num = int(page_num) # 字符串类型,所以要转成int except Exception as e: self.page_num = 1 self.total_count = total_count self.base_url = base_url self.per_page_num = per_page_num self.max_show = max_show # 根据传进来的参数,计算的几个值 self.half_show = int((self.max_show - 1) / 2) # 总共有多少页 self.total_page_num, more = divmod(self.total_count, self.per_page_num) if more: self.total_page_num += 1 @property def start(self): return (self.page_num - 1) * self.per_page_num @property def end(self): return self.page_num * self.per_page_num def page_html(self): """ 返回页面上可以用的一段HTML 一段可用的分页页码的HTML :return: """ # 页面上页码从哪儿开始 page_start = self.page_num - self.half_show # 页面上页码最多展示到哪一个 page_end = self.page_num + self.half_show # 如果当前页小于等于half_show, 默认从第一页展示到max_show if self.page_num <= self.half_show: page_start = 1 page_end = self.max_show # 如果当前页大于等于总页数-half_show if self.page_num >= self.total_page_num - self.half_show: page_end = self.total_page_num page_start = self.total_page_num - self.max_show # 生成前页码的HTML page_html_list = [] # 放置一个首页按钮 page_first_tmp = ‘<li><a href="{}?page=1">首页</a></li>‘.format( self.base_url) page_html_list.append(page_first_tmp) # 加上一页按钮 if self.page_num - 1 <= 0: # 表示没有上一页 page_prev_tmp = ‘<li class="disabled" ><a href="#">上一页</a></li>‘ else: page_prev_tmp = ‘<li><a href="{0}?page={1}">上一页</a></li>‘.format( self.base_url, self.page_num - 1) page_html_list.append(page_prev_tmp) for i in range(page_start, page_end+1): # 如果是当前页,就加一个active的样式 if i == self.page_num: tmp = ‘<li class="active"><a href="{0}?page={1}">{1}</a></li>‘.format( self.base_url, i) else: tmp = ‘<li><a href="{0}?page={1}">{1}</a></li>‘.format( self.base_url, i) page_html_list.append(tmp) # 加下一页按钮 if self.page_num+1 > self.total_page_num: page_next_tmp = ‘<li class="disabled"><a href="#">下一页</a></li>‘ else: page_next_tmp = ‘<li><a href="{0}?page={1}">下一页</a></li>‘.format( self.base_url, self.page_num+1) page_html_list.append(page_next_tmp) # 添加一个尾页 page_last_tmp = ‘<li><a href="{0}?page={1}">尾页</a></li>‘.format( self.base_url, self.total_page_num) page_html_list.append(page_last_tmp) return "".join(page_html_list)
上面封装的这个类中,第一第二个函数就已经可以打印出列表了,第三个函数可以打印出分页按钮,层次非常的鲜明。
最后展示一下效果,其中样式调用了bootstarp。