Django项目实战—分页
自定义分页
未封装版:
- 优点:直观
- 缺点:代码乱,不易维护,可拓展性差
data = [] for i in range(1, 302):
tmp = {"id": i, "name": "alex-{}".format(i)}
data.append(tmp) print(data) def user_list(request): # user_list = data[0:10]
# user_list = data[10:20]
try:
current_page = int(request.GET.get("page"))
except Exception as e:
current_page = 1 per_page = 10 # 数据总条数
total_count = len(data)
# 总页码
total_page, more = divmod(total_count, per_page)
if more:
total_page += 1 # 页面最多显示多少个页码
max_show = 11
half_show = int((max_show-1)/2) if current_page <= half_show:
show_start = 1
show_end = max_show
else:
if current_page + half_show >= total_page:
show_start = total_page - max_show
show_end = total_page
else:
show_start = current_page - half_show
show_end = current_page + half_show # 数据库中获取数据
data_start = (current_page - 1) * per_page
data_end = current_page * per_page user_list = data[data_start:data_end] # 生成页面上显示的页码
page_html_list = []
# 加首页
first_li = '<li><a href="/user_list/?page=1">首页</a></li>'
page_html_list.append(first_li)
# 加上一页
if current_page == 1:
prev_li = '<li><a href="#">上一页</a></li>'
else:
prev_li = '<li><a href="/user_list/?page={}">上一页</a></li>'.format(current_page - 1)
page_html_list.append(prev_li)
for i in range(show_start, show_end+1):
if i == current_page:
li_tag = '<li class="active"><a href="/user_list/?page={0}">{0}</a></li>'.format(i)
else:
li_tag = '<li><a href="/user_list/?page={0}">{0}</a></li>'.format(i)
page_html_list.append(li_tag) # 加下一页
if current_page == total_page:
next_li = '<li><a href="#">下一页</a></li>'
else:
next_li = '<li><a href="/user_list/?page={}">下一页</a></li>'.format(current_page+1)
page_html_list.append(next_li) # 加尾页
page_end_li = '<li><a href="/user_list/?page={}">尾页</a></li>'.format(total_page)
page_html_list.append(page_end_li) page_html = "".join(page_html_list) return render(request, "user_list.html", {"user_list": user_list, "page_html": page_html})
封装版:
- 优点:易维护、可拓展性强
- 缺点:逻辑相对复杂
"""
自定义分页组件
"""
class Pagination(object): def __init__(self, data_num, current_page, url_prefix, per_page=10, max_show=11):
"""
进行初始化.
:param data_num: 数据总数
:param current_page: 当前页
:param url_prefix: 生成的页码的链接前缀
:param per_page: 每页显示多少条数据
:param max_show: 页面最多显示多少个页码
"""
self.data_num = data_num
self.per_page = per_page
self.max_show = max_show
self.url_prefix = url_prefix # 把页码数算出来
self.page_num, more = divmod(data_num, per_page)
if more:
self.page_num += 1 try:
self.current_page = int(current_page)
except Exception as e:
self.current_page = 1
# 如果URL传过来的页码数是负数
if self.current_page <= 0:
self.current_page = 1
# 如果URL传过来的页码数超过了最大页码数
elif self.current_page > self.page_num:
self.current_page = self.page_num # 默认展示最后一页 # 页码数的一半 算出来
self.half_show = max_show // 2 # 页码最左边显示多少
if self.current_page - self.half_show <= 1:
self.page_start = 1
self.page_end = self.max_show
elif self.current_page + self.half_show >= self.page_num: # 如果右边越界
self.page_end = self.page_num
self.page_start = self.page_num - self.max_show
else:
self.page_start = self.current_page - self.half_show
# 页码最右边显示
self.page_end = self.current_page + self.half_show if self.page_num < self.page_end:
self.page_end = self.page_num # 如果总页面小于结束页面,那么结束页面即为总页码 @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):
# 生成页码
l = []
# 加一个首页
l.append('<li><a href="{}?page=1">首页</a></li>'.format(self.url_prefix))
# 加一个上一页
if self.current_page == 1:
l.append('<li class="disabled" ><a href="#">«</a></li>'.format(self.current_page))
else:
l.append('<li><a href="{}?page={}">«</a></li>'.format(self.url_prefix, self.current_page - 1)) for i in range(self.page_start, self.page_end + 1): if i == self.current_page:
tmp = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
else:
tmp = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
l.append(tmp) # 加一个下一页
if self.current_page == self.page_num:
l.append('<li class="disabled"><a href="#">»</a></li>'.format(self.current_page))
else:
l.append('<li><a href="{}?page={}">»</a></li>'.format(self.url_prefix, self.current_page + 1))
# 加一个尾页
l.append('<li><a href="{}?page={}">尾页</a></li>'.format(self.url_prefix, self.page_num))
return "".join(l)
封装版使用步骤:
- 将上面的一段代码复制到自定义的模块(pt文件)中
- 导入自定义模块
- 在views系统的函数里写入以下代码
def user_list(request):
# 实例化一个分页类的对象
obj = Pagination(blogs.count(),page,'blogs.html')
# 根据传入的总博客数、页码获取当页需要展示的博客
blog_list = blogs[obj.start:obj.end]
# 根据传入的博客数及页码获取生成分页的html格式的页码列表
page_html = pager.page_html()
#返回指定页面
return render(request, "blog_list.html", {"blog_list": blog_list, "page_html": page_html}) - 在需要生成页面的html页面写入以下代码
<div class="topicListFooter fenye">
<ul class="pagination">
{{ page_html|safe }}
</ul>
</div>注:示例中用的是bootstrap分页样式
Django中的内置分页(不能展示页码列表)
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger L = []
for i in range(999):
L.append(i) def index(request):
current_page = request.GET.get('p') paginator = Paginator(L, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
try:
posts = paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts}) 内置分页view部分
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
{% for item in posts %}
<li>{{ item }}</li>
{% endfor %}
</ul> <div class="pagination">
<span class="step-links">
{% if posts.has_previous %}
<a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
</span>
{% if posts.has_next %}
<a href="?p={{ posts.next_page_number }}">Next</a>
{% endif %}
</span> </div>
</body>
</html> 内置分页HTML部分
Django项目实战—分页的更多相关文章
- Django项目实战之用户上传与访问
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...
- Django项目实战之用户头像上传与访问
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> < ...
- 跟老齐学Django 项目实战笔记
创建项目 mysite 创建应用 blog mysit/settings.py配置app INSTALLED_APPS = [ 'django.contrib.admin', 'django.cont ...
- Django项目实战—用户头像上传
1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...
- Django项目实战 - 搜索功能(转)
首先,前端已实现搜索功能页面, 我们直接写后台逻辑: Q()可以实现 逻辑或的判断, name_ _ icontains 表示 name字段包含搜索的内容,i表示忽略大小写. from djang ...
- Django项目实战 - html中用户登录判断
实现逻辑: {% if request.user.is_authenticated %} 个人信息{% else %}登录{% endif %} 直接上代码 {% if request.user.is ...
- 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程
点击了解更多Python课程>>> 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程 适用人群: 即将毕业的大学生,工资低工作重的白领,渴望崭露头角的职场新人, ...
- web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 ☝☝☝
web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 学习 ...
- Python Django CMDB项目实战之-3创建form表单,并在前端页面上展示
基于之前的项目代码 Python Django CMDB项目实战之-1如何开启一个Django-并设置base页.index页.文章页面 Python Django CMDB项目实战之-2创建APP. ...
随机推荐
- NLP之ROUGE[笔记]
0 前言 [定义]ROUGE:recall-oriented understanding for gisting evaluation,面向召回的要点评估理解 召回率,recall rate;要点,g ...
- 运行React Native项目出现白屏,无法运行
运行React Native出现白屏,无法运行,查看终端报错如下: 原因: 代码中有语法错误,导致运行失败. 其实到这里可以去Xcode查看控制台打印,会提示哪个文件出现错误的. 解决办法: 找到报错 ...
- Vue学习笔记(四)一起进阶吧
参考链接地址:https://segmentfault.com/a/1190000009188689?from=timeline Vuex框架原理与源码分析: http://tech.meituan. ...
- php微信支付企业付款到零钱报错call faild, errorCode:58
这个报错一般是自己证书目录不是绝对目录,正确的目录结构应该是网站根目录下的:“C:\PHPWAMP_IN1\wwwroot\XXXX\XXXX.pem”. 还要注意的是文件夹命名一定 ...
- opengl鼠标键盘控制相机漫游
键盘wsad控制相机位移,鼠标左键按下控制相机旋转 效果如下 代码如下 #include <stdio.h> #include <string.h> #include < ...
- opengl球形网格生成
效果如图 准备第三方库 glew.freeglut.glm 代码包括主程序源文件mainApp.cpp.顶点着色器shader.vs.片元着色器shader.fs mainApp.cpp如下 #i ...
- Flutter之ExpansionTile组件
ExpansionTile组件 ExpansionTile Widget就是一个可以展开闭合的组件,常用的属性有如下几个. title:闭合时显示的标题,这个部分经常使用Text Widget. le ...
- 移动端自动化测试之android模拟器问题集合
黑屏 在做移动端自动化测试过程中,android模拟器启动黑屏的问题一直困扰着我,网上找了许多方法尝试了都不能解决我的问题,最后重新安装了镜像文件,问题才得以解决,当然并不是网上的解决办法都是错的,只 ...
- [Python[PyQt]] ModuleNotFoundError: No module named 'PyQt5.QtWebEngineWidgets'
解决办法: pip install PyQtWebEngine
- 除了 UCAN 发布的鹿班和普惠体,这些设计工具也来自阿里
在 4 月 27 日的 UCAN 2019 设计大会上,阿里巴巴对外发布了一款全新免费字体——阿里巴巴普惠体.其实,作为经济体的阿里巴巴,这些年早已默默推出了很多实用的设计工具,比如大名鼎鼎的 Ico ...