[Django高级之批量插入数据、分页器组件]

批量插入数据

模板层models.py

  1. from django.db import models
  2. class Books(models.Model):
  3. name = models.CharField(max_length=32)
  4. price = models.DecimalField(max_digits=8,decimal_places=2)
  5. publish = models.CharField(max_length=32)

建表别忘了执行数据库迁移命令哦

  1. python3 manage.py makemigrations
  2. python3 manage.py migrate

路由层urls.py

  1. urlpatterns = [
  2. url(r'^books_page/', views.books_page),
  3. ]

视图层views.py

  1. # 往Book表里批量插入数据
  2. def books_page(request):
  3. # 第一种方案,每循环一次,操作一下数据库,性能低(相当于进行了1000次的数据库链接)
  4. # for i in range(1000):
  5. # book=models.Books.objects.create(name='图书%s'%i,price=i+10,publish='东京出版社')
  6. #
  7. --------------------------------------------------------------------------------------
  8. # 第二种方案,批量插入
  9. book_list=[] # 实例化对象放到列表里
  10. for i in range(1000):
  11. book=models.Books(name='图书%s'%i,price=i+10,publish='东京出版社')
  12. book_list.append(book)
  13. # bulk_create一次性插入,batch_size分批往里面插
  14. models.Books.objects.bulk_create(book_list,batch_size=100) # batch_size 指定一批数量
  15. return HttpResponse('ok')
  16. # 当你想要批量插入数据的时候,使用ORM提供的 bulk_create 能够大大的减少操作时间

自定义分页器

针对上一小节批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便

针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理

分页推导

首先我们需要明确的时候,get请求也是可以携带参数的,所以我们在朝后端发送查看数据的同时可以携带一个参数告诉后端我们想看第几页的数据

其次我们还需要知道一个点,queryset对象是支持索引取值和切片操作的,但是不支持负数索引情况

接下来我们就可以推导我们的自定义分页器步骤了

  1. current_page = request.GET.get("page",1) # 获取用户想访问的页码 如果没有 默认展示第一页
  2. try: # 由于后端接受到的前端数据是字符串类型所以我们这里做类型转换处理加异常捕获
  3. current_page = int(current_page)
  4. except Exception as e:
  5. current_page = 1
  6. # 还需要定义页面到底展示几条数据
  7. per_page_num = 10 # 一页展示10条数据
  8. # 需要对总数据进行切片操作 需要确定切片起始位置和终止位置
  9. start_page = ?
  10. end_page = ?
  11. """
  12. 下面需要研究current_page、per_page_num、start_page、end_page四个参数之间的数据关系
  13. per_page_num = 10
  14. current_page start_page end_page
  15. 1 0 10
  16. 2 10 20
  17. 3 20 30
  18. 4 30 40
  19. per_page_num = 5
  20. current_page start_page end_page
  21. 1 0 5
  22. 2 5 10
  23. 3 10 15
  24. 4 15 20
  25. 可以很明显的看出规律
  26. start_page = (current_page - 1) * per_page_num
  27. end_page = current_page* per_page_num
  28. """

数据总页面获取

当我问你下面几个问题的时候,你的内心肯定是鄙视的,不信的话那就请听题

问题1:总数据有100条,每页展示10条,总共需要几页?

答案:10条

问题2:总数据有101条,每页展示10条,总共需要几页?

答案:11条

问题3:如何通过代码算出到底需要多少条?

答案:去你妹的,不会!!!

内置方法之divmod

  1. >>> divmod(100,10)
  2. (10, 0) # 10页
  3. >>> divmod(101,10)
  4. (10, 1) # 11页
  5. >>> divmod(99,10)
  6. (9, 9) # 10页
  7. # 余数只要不是0就需要在第一个数字上加一

我们可以判断元祖的第二个数字是否为0从而确定到底需要多少页来展示数据

  1. book_queryset = models.Book.objects.all()
  2. all_count = book_queryset.count() # 数据总条数
  3. all_pager, more = divmod(all_count, per_page_num)
  4. if more: # 有余数则总页数加一
  5. all_pager += 1

至此分页器大致的功能及思路我们就已经大致清楚了

最后我们只需要利用start_page和end_page对总数据进行切片取值再传入前端页面就能够实现分页展示

  1. book_list = models.Book.objects.all()[start_page:end_page]
  2. return render(request,'booklist.html',locals())

接下来就是前端页面的代码编写了

  1. {% for book in book_list %}
  2. <p>{{ book.title }}</p>
  3. {% endfor %}

现在我们实现了最简单的分页,但是前端没有按钮去让用户点击需要看第几页,所以我们需要渲染分页器相关代码,这里我们不做要求直接去bootstrap框架拷贝代码即可

终极大法

上面是自定义分页器开发流程的基本思路,我们不需要掌握代码的编写,只需要掌握基本用法即可

自定义分页器封装代码

  1. class Pagination(object):
  2. def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
  3. """
  4. 封装分页相关数据
  5. :param current_page: 当前页
  6. :param all_count: 数据库中的数据总条数
  7. :param per_page_num: 每页显示的数据条数
  8. :param pager_count: 最多显示的页码个数
  9. """
  10. try:
  11. current_page = int(current_page)
  12. except Exception as e:
  13. current_page = 1
  14. if current_page < 1:
  15. current_page = 1
  16. self.current_page = current_page
  17. self.all_count = all_count
  18. self.per_page_num = per_page_num
  19. # 总页码
  20. all_pager, tmp = divmod(all_count, per_page_num)
  21. if tmp:
  22. all_pager += 1
  23. self.all_pager = all_pager
  24. self.pager_count = pager_count
  25. self.pager_count_half = int((pager_count - 1) / 2)
  26. @property
  27. def start(self):
  28. return (self.current_page - 1) * self.per_page_num
  29. @property
  30. def end(self):
  31. return self.current_page * self.per_page_num
  32. def page_html(self):
  33. # 如果总页码 < 11个:
  34. if self.all_pager <= self.pager_count:
  35. pager_start = 1
  36. pager_end = self.all_pager + 1
  37. # 总页码 > 11
  38. else:
  39. # 当前页如果<=页面上最多显示11/2个页码
  40. if self.current_page <= self.pager_count_half:
  41. pager_start = 1
  42. pager_end = self.pager_count + 1
  43. # 当前页大于5
  44. else:
  45. # 页码翻到最后
  46. if (self.current_page + self.pager_count_half) > self.all_pager:
  47. pager_end = self.all_pager + 1
  48. pager_start = self.all_pager - self.pager_count + 1
  49. else:
  50. pager_start = self.current_page - self.pager_count_half
  51. pager_end = self.current_page + self.pager_count_half + 1
  52. page_html_list = []
  53. # 添加前面的nav和ul标签
  54. page_html_list.append('''
  55. <nav aria-label='Page navigation>'
  56. <ul class='pagination'>
  57. ''')
  58. first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
  59. page_html_list.append(first_page)
  60. if self.current_page <= 1:
  61. prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
  62. else:
  63. prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
  64. page_html_list.append(prev_page)
  65. for i in range(pager_start, pager_end):
  66. if i == self.current_page:
  67. temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
  68. else:
  69. temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
  70. page_html_list.append(temp)
  71. if self.current_page >= self.all_pager:
  72. next_page = '<li class="disabled"><a href="#">下一页</a></li>'
  73. else:
  74. next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
  75. page_html_list.append(next_page)
  76. last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
  77. page_html_list.append(last_page)
  78. # 尾部添加标签
  79. page_html_list.append('''
  80. </nav>
  81. </ul>
  82. ''')
  83. return ''.join(page_html_list)

自定义分页器使用

后端

  1. def get_book(request):
  2. book_list = models.Book.objects.all()
  3. current_page = request.GET.get("page",1)
  4. all_count = book_list.count()
  5. page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
  6. page_queryset = book_list[page_obj.start:page_obj.end]
  7. return render(request,'booklist.html',locals())

前端

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-8 col-md-offset-2">
  4. {% for book in page_queryset %}
  5. <p>{{ book.title }}</p>
  6. {% endfor %}
  7. {{ page_obj.page_html|safe }}
  8. </div>
  9. </div>
  10. </div>

[Django高级之批量插入数据、分页器组件]的更多相关文章

  1. django ajax 及批量插入数据 分页器

    ``` Ajax 前端朝后端发送请求都有哪些方式 a标签href GET请求 浏览器输入url GET请求 form表单 GET/POST请求 Ajax GET/POST请求 前端朝后端发送数据的编码 ...

  2. Django orm 实现批量插入数据

    Django ORM 中的批量操作 在Hibenate中,通过批量提交SQL操作,部分地实现了数据库的批量操作.但在Django的ORM中的批量操作却要完美得多,真是一个惊喜. 数据模型定义 首先,定 ...

  3. Django向数据库批量插入数据

    # 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...

  4. django与ajax:ajax结合sweetalter ,批量插入数据 ;分页器组件

    目录 一.ajax结合sweetalter 二.bulk_create批量插入数据 三.简易版分页器推导 1. 推导步骤 四.自定义分页器的使用 1. 自定义分页器模板 2. 使用方法 (1)后端代码 ...

  5. Django批量插入数据和分页器

    目录 一.ajax结合sweetalert实现删除按钮动态效果 二.bulk_create批量插入数据 1. 一条一条插入 2. 批量插入 三.自定义分页器 一.ajax结合sweetalert实现删 ...

  6. django----Sweetalert bulk_create批量插入数据 自定义分页器

    目录 一.Sweetalert使用AJAX操作 二.bulk_create 三.分页器 divmod 分页器组件 自定义分页器的使用 一.Sweetalert使用AJAX操作 ​ sweetalert ...

  7. MySQL高级知识(十)——批量插入数据脚本

    前言:使用脚本进行大数据量的批量插入,对特定情况下测试数据集的建立非常有用. 0.准备 #1.创建tb_dept_bigdata(部门表). create table tb_dept_bigdata( ...

  8. (day56)八、删除框、批量创建、分页器组件

    目录 一.ajax结合sweetalert实现删除按钮的动态效果 二.bulk_create批量插入数据 三.自定义分页器 (一)手动推导 (二)自定义分页器 (1)模板 (2)用法 一.ajax结合 ...

  9. jmeter应用之批量插入数据

    上一篇讲到如何在jmeter中配置并连接使用mysql数据库,这一节主要是讲数据库连接的简单应用——批量插入数据 总体步骤如下: 1)新建线程组和添加JDBC Connection Configura ...

随机推荐

  1. 2.EL表达式&JSTL标签库常用方法

    1.EL表达式 Expression Language表达式语言,主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出. 格式为${表达式} EL表达式输出Bean的普通属性.数组属性.Li ...

  2. 《MySQL必知必会》学习笔记整理

    简介 此笔记只包含<MySQL必知必会>中部分章节的整理笔记.这部分章节主要是一些在<SQL必知必会>中并未讲解的独属于 MySQL 数据库的一些特性,如正则表达式.全文本搜索 ...

  3. Django 模板(Template)

    1. 模板简介 2. 模板语言 DTL 3. 模板继承 4. HTML 转义 5. CSRF 1. 模板简介 作为 Web 开发框架,Django 提供了模板,可以很便利的动态生成 HTML.模版系统 ...

  4. Mysql 8.0安装

    1. 下载安装包至/usr/local目录下 下载地址:https://cdn.mysql.com/Downloads/MySQL-8.0/mysql-8.0.16-el7-x86_64.tar.gz ...

  5. SQL注入平台第一关,注入?id=1'不报错的问题

    第一关需要在地址栏输入id参数测试是否有注入点 我这里输入 http://localhost/sqli-labs-master/Less-1/?id=1 下一步将id参数改为?id=1' http:/ ...

  6. (CV学习笔记)看图说话(Image Captioning)-1

    Background 分别使用CNN和LSTM对图像和文字进行处理: 将两个神经网络结合: 应用领域 图像搜索 安全 鉴黄 涉猎知识 数字图像处理 图像读取 图像缩放 图像数据纬度变换 自然语言处理 ...

  7. vscode 将本地项目上传到github、从github克隆项目以及删除github上的某个文件夹

    一.将本地项目上传到github 1.创建本地仓库(文件夹) mkdir study//创建文件夹studycd study //进入study文件夹 2.通过命令git init把这个文件夹变成Gi ...

  8. layui中流加载layui.flow

    1.引入layui.css和layui.js 2. html中定义容器 <div id="demo"></div> js部分: layui.use('flo ...

  9. 【Linux】在centos中使用命令安装redis

    1.前提centos能够上网 测试方式输入命令,有数据返回即可.如果则先配置centos网络连接. ping www.baidu.com 2.安装gcc 输入命令进行安装 yum install gc ...

  10. js--吐血总结最近遇到的变态表单校验---element+原生+jq+easyUI(前端职业生涯见过的最烦的校验)

    最近写了无数各种形式的表单,记录下奇奇怪怪的校验规则~ 一:首先是element自带的rules校验规则: element作为常用框架,自带rules属性简单易懂,官方文档一目了然,不再赘述,应付常用 ...