Django之批量插入数据、 自定义分页器
文章目录
- 一、 批量插入数据
- 方法一:
- 方法二: 批量插入bulk_create方法
- 二、 自定义分页器
- 2.1 分页推导
- 2.2 数据总页面获取
- 2.3 内置方法之divmod
- 三、 自定义分页器终极大法
一、 批量插入数据
项目需求:浏览器中访问django后端某一条url(如:127.0.0.1:8080/index/),实时朝数据库中生成一千条数据并将生成的数据查询出来,并展示到前端页面
urls.py
from django.conf.urls import url
from app01 import viewsurlpatterns = [url(r'^get_book/',views.get_book)
]
models.py
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=64)
template/get_book.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>{% load static %}<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"><link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}"><script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script><script src="{% static 'dist/sweetalert.min.js' %}"></script>
</head>
<body>
<div class="container"><div class="row"><div class="col-md-8 col-md-offset-2">{% for book in book_queryset %}<p>{{ book.title }}</p>{% endfor %}</div></div>
</div>
</body>
</html>
方法一:
views.py
from django.shortcuts import render, HttpResponse, redirect
from app01 import modelsdef get_book(request):# for循环插入1000条数据for i in range(1000):models.Book.objects.create(name='第%s本书'%i)# 将插入的数据再查询出来book_queryset = models.Book.objcets.all()return render(request,'get_book.html',locals()) # 将查询出来的数据传递给html页面
上述代码书写完毕后启动django后端,浏览器访问,会发现浏览器会有一个明显的卡顿等待时间,这不是你的浏览器有问题也不是网速有问题,而是后端再不停的操作数据库,耗时较长,大概需要等待一段时间之后才能正常看到刚刚插入的1000条数据,很明显这样操作数据库的效率太低,那有没有一种方式是专门用来批量操作数据库的呢?答案是肯定的!
方法二: 批量插入bulk_create方法
将views.py中原先的视图函数稍作变化
def book(request):l = []for i in range(10000):l.append(models.Book(title='第%s本书'%i))models.Book.objects.bulk_create(l) # 批量插入数据return render(request,'booklist.html',locals())
代码修改完毕之后其他地方无需改动,重启django项目浏览器重新访问,你会立马发现数据量增大十倍的情况下页面出现的速度居然还比上面的版本要快上速度倍!!!
bulk_create方法是django orm特地提供给我们的方便批量操作数据库的方式,效率非常高!!!
二、 自定义分页器
针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理
2.1 分页推导
首先我们需要明确的时候,get请求也是可以携带参数的,所以我们在朝后端发送查看数据的同时可以携带一个参数告诉后端我们想看第几页的数据
其次我们还需要知道一个点,queryset对象是支持索引取值和切片操作的,但是不支持负数索引情况
接下来我们就可以推导我们的自定义分页器步骤了
current_page = request.GET.get("page",1) # 获取用户想访问的页码 如果没有 默认展示第一页
try: # 由于后端接受到的前端数据是字符串类型所以我们这里做类型转换处理加异常捕获current_page = int(current_page)
except Exception as e:current_page = 1
# 还需要定义页面到底展示几条数据
per_page_num = 10 # 一页展示10条数据# 需要对总数据进行切片操作 需要确定切片起始位置和终止位置
start_page = ?
end_page = ?
"""
下面需要研究current_page、per_page_num、start_page、end_page四个参数之间的数据关系
per_page_num = 10
current_page start_page end_page1 0 102 10 203 20 30 4 30 40per_page_num = 5
current_page start_page end_page1 0 52 5 103 10 15 4 15 20
可以很明显的看出规律
start_page = (current_page - 1) * per_page_num
end_page = current_page* per_page_num
"""
2.2 数据总页面获取
当我问你下面几个问题的时候,你的内心肯定是鄙视的,不信的话那就请听题
问题1:总数据有100条,每页展示10条,总共需要几页?
答案:10条
问题2:总数据有101条,每页展示10条,总共需要几页?
答案:11条
问题3:如何通过代码算出到底需要多少条?
答案:去你妹的,不会!!!
2.3 内置方法之divmod
>>> divmod(100,10)
(10, 0) # 10页
>>> divmod(101,10)
(10, 1) # 11页
>>> divmod(99,10)
(9, 9) # 10页
# 余数只要不是0就需要在第一个数字上加一
我们可以判断元祖的第二个数字是否为0从而确定到底需要多少页来展示数据
book_queryset = models.Book.objects.all()
all_count = book_queryset.count() # 数据总条数
all_pager, more = divmod(all_count, per_page_num)
if more: # 有余数则总页数加一all_pager += 1
至此分页器大致的功能及思路我们就已经大致清楚了
最后我们只需要利用start_page和end_page对总数据进行切片取值再传入前端页面就能够实现分页展示
book_list = models.Book.objects.all()[start_page:end_page]
return render(request,'booklist.html',locals())
接下来就是前端页面的代码编写了
{% for book in book_list %}<p>{{ book.title }}</p>
{% endfor %}
现在我们实现了最简单的分页,但是前端没有按钮去让用户点击需要看第几页,所以我们需要渲染分页器相关代码,这里我们不做要求直接去bootstrap框架拷贝代码即可
三、 自定义分页器终极大法
上面是自定义分页器开发流程的基本思路,我们不需要掌握代码的编写,只需要掌握基本用法即可
自定义分页器封装代码
class Pagination(object):def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):"""封装分页相关数据:param current_page: 当前页:param all_count: 数据库中的数据总条数:param per_page_num: 每页显示的数据条数:param pager_count: 最多显示的页码个数"""try:current_page = int(current_page)except Exception as e:current_page = 1if current_page < 1:current_page = 1self.current_page = current_pageself.all_count = all_countself.per_page_num = per_page_num# 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pagerself.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2)@propertydef start(self):return (self.current_page - 1) * self.per_page_num@propertydef end(self):return self.current_page * self.per_page_numdef page_html(self):# 如果总页码 < 11个:if self.all_pager <= self.pager_count:pager_start = 1pager_end = self.all_pager + 1# 总页码 > 11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page <= self.pager_count_half:pager_start = 1pager_end = self.pager_count + 1# 当前页大于5else:# 页码翻到最后if (self.current_page + self.pager_count_half) > self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1page_html_list = []# 添加前面的nav和ul标签page_html_list.append('''<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="#">上一页</a></li>'else:prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)page_html_list.append(prev_page)for i in range(pager_start, pager_end):if i == self.current_page:temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)else:temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)page_html_list.append(temp)if self.current_page >= self.all_pager:next_page = '<li class="disabled"><a href="#">下一页</a></li>'else:next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)page_html_list.append(next_page)last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)page_html_list.append(last_page)# 尾部添加标签page_html_list.append('''</nav></ul>''')return ''.join(page_html_list)
自定义分页器使用
后端
def get_book(request):book_list = models.Book.objects.all()current_page = request.GET.get("page",1)all_count = book_list.count()page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)page_queryset = book_list[page_obj.start:page_obj.end]return render(request,'booklist.html',locals())
前端只需要这一行代码就可以实现分页
<div class="text-center">{{ page_obj.page_html|safe }}</div>
前端
<div class="container"><div class="row"><div class="col-md-8 col-md-offset-2">{% for book in page_queryset %}<p>{{ book.title }}</p>{% endfor %}<div class="text-center">{{ page_obj.page_html|safe }}</div></div></div>
</div>
Django之批量插入数据、 自定义分页器相关推荐
- django11:自动序列化/批量插入数据/分页器
自动序列化 借助serializers帮你自动完成序列化 from app01 import models from django.core import serializers def ab_se( ...
- Django批量插入数据
数据模型如下: from django.db import models# Create your models here. class GradingModels(models.Model):use ...
- python加数据库_用python批量插入数据到数据库中
既然使用python操作数据库必不可少的得使用pymysql模块 可使用两种方式进行下载安装: 1.使用pip方式下载安装 pip install pymysql 2.IDE方式 安装完成后就可以正常 ...
- MyBatis 批量插入数据的 3 种方法
批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...
- 批量插入数据库语句java_java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码)...
java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码) 发布于 2020-7-22| 复制链接 本文通过实例代码给大家分享了MyBatis批量插入数据到Oracle数据库 ...
- oracle insert汉字出错,Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名...
本文主要向大家介绍了Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名,通过具体的内容向大家展现,希望对大家学习Oracle数据库有所帮助. Oracle数据库,用 ...
- linux批量es数据,Elasticsearch批量插入数据
Elasticsearch批量插入数据 使用bulk批量操作数据库 1. 创建批量操作文件 格式: {"index":{"_index":"home& ...
- android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)
android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本) 参考文章: (1)android SQLite 批量插入数据慢的解决方案 (针对于不同的andro ...
- php addall,ThinkPHP3.2框架使用addAll()批量插入数据的方法
这篇文章主要介绍了ThinkPHP3.2框架使用addAll()批量插入数据的方法,结合实例形式分析了thinkPHP针对单条数据插入及批量数据插入操作的相关实现技巧,需要的朋友可以参考下 本文实例讲 ...
最新文章
- 【怎样写代码】参数化类型 -- 泛型(四):泛型之类型参数约束
- 大公司为什么还在采用过时的技术
- 3·15,你“信”了吗
- php编程实现单入口,apache配置php实现单一入口方法
- python大型项目经验_经验丰富程序员才知道的8种高级Python技巧
- win10高危服务_IPv6用户危险了!Win10出现严重安全漏洞
- tablayout 动态改变标题_描点法画函数图像的动态演示——动态数学软件GeoGebra制作教程...
- Linux常用的基本命令13
- I,P,B帧和PTS,DTS的关系,GOP相关
- comsol和java_COMSOL java API——编译comsol模型java文件
- TCP、UDP、Socket、HTTP网络编程面试题(总结最全面的面试题)
- 嵌入式软件工程师笔试面试指南目录
- Command Line Tools下载不下来,则可以去官网下载
- SLIC超像素算法学习笔记
- Android自定义view之围棋动画(化繁为简)
- 如何将PDF的单页页面分割成多个页面,如何将PDF页面的四周空白部分裁剪掉
- 2010年北京大学软件与微电子学院毕业生就业去向(官方不完全统计)
- 34岁程序员月薪3万2,跳槽被国企录取,看到月收入后却犹豫了!
- 人工智能的落地及未来的发展
- Codevs 1066 引水入城 2010年NOIP全国联赛提高组 BFS + 贪心