day11 序列化组件、批量出入、自定义分页器

今日内容详细

  • ajax实现删除二次提醒(普通版本)
  • ajax结合第三方插件sweetalert实现二次提醒(样式好看些)
  • ajax如何发送文件数据
  • ajax核心参数之dataType
  • django序列化组件(自带的)
  • 自定义分页器(django自带一个分页器只不过不好用)
  • 自定义分页器的固定使用方式

使用Ajax实现二次确认删除功能

  1. # 使用ajax就不能使用下面的url,会造成冲突
  2. <a href="{% url 'bd' book_obj.pk %}" class="btn btn-danger btn-xs">删除</a> # 修改前
  3. <a href="#" class="btn btn-danger btn-xs c1" delete_id="{{ book_obj.pk }}">删除</a> # 修改后
  4. # // 标签既可以有默认的属性,也可以有自定义的属性,添加delete_id是可以获取主键id值
  5. # views.py
  6. def del_book(request):
  7. # 判断当前请求是否为ajax请求
  8. if request.is_ajax():
  9. if request.method == 'POST': # 判断是否是ajax发来的post请求
  10. # 拿到ajax传到后端的data值
  11. delete_id = request.POST.get('delete_id')
  12. # 根据传过来的主键id删除数据
  13. models.Book.objects.filter(pk=delete_id).delete()
  14. return HttpResponse('删除成功!')
  15. # book_list.html
  16. {% block js %}
  17. <script>
  18. var $btn = $('.c1'); // 找到c1标签
  19. // 绑定点击事件
  20. $btn.on('click',function () {
  21. var delete_id = $(this).attr('delete_id'); // 拿当前点击按钮中的delete_id属性
  22. var $this = $(this); // 给this设置一个变量
  23. {#alert(delete_id); // 试验是否拿到主键id#}
  24. // 做提醒效果
  25. let res = confirm('确定删除吗');
  26. // 判断是否为true
  27. if (res){ //true
  28. // 发送ajax请求
  29. $.ajax({
  30. url:'/del_book/', // 向它发送请求
  31. type:'post',
  32. data:{'delete_id':delete_id},
  33. success:function (args) {
  34. alert(args) ; // 接收到用户后端穿过来数据,代表已经删除成功
  35. // 刷新页面
  36. {#window.location.reload()#}
  37. // js代码自动刷新
  38. $this.parent().parent().remove()
  39. }
  40. })
  41. }else { // false
  42. return false
  43. }
  44. })
  45. </script>
  46. {% endblock %}
  47. '''
  48. 总结:
  49. 1.先在a标签中添加一个自定义属性:delete_id={{book_obj.pk}},并且设置一个c1标签
  50. 2.找到c1标签,并且绑定一个点击事件
  51. 3.拿当前点击按钮中的delete_id属性
  52. 4.做提醒效果
  53. 5.判断是否为true
  54. 6.真的话:向后端发送ajax请求,并且其中把主键id传入到后端
  55. 7.在路由层和视图层开设出相应的函数
  56. 8.后端拿到ajax发来的主键id,根据主键id删除数据库数据,并给前端返回一个结果
  57. 9.前端拿到返回结果并打印,并刷新页面
  58. '''
  59. # 存在的问题:
  60. window.location.reload()
  61. 当有多个页面时,使用上面的方法,会直接刷新到首页,会给用户造成不好的体验
  62. # 解决:
  63. 可以根据js代码自动删除,通过代码把tr标签删除
  64. var $this = $(this); // 给this设置一个变量
  65. // js代码自动刷新
  66. $this.parent().parent().remove()

试验url是否可以用反向解析

  1. # 试验url是否可以用反向解析
  2. <script>
  3. var $btn = $('.c1');
  4. $btn.on('click',function () {
  5. $.ajax({
  6. url:'{% url "bl" %}',
  7. type: 'post',
  8. data:'',
  9. succees:function () {
  10. }
  11. })
  12. })
  13. </script>
  14. [02/Dec/2021 16:58:16] "POST /del_book/ HTTP/1.1" 200 15 # 发送了一个post请求,证明是可以的

结合第三方模块实现二次确认删除功能

  1. {% block js %}
  2. <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  3. <script>
  4. var $btn = $('.c1'); // 找到c1标签
  5. // 绑定点击事件
  6. $btn.on('click',function (){
  7. var delete_id = $(this).attr('delete_id'); // 拿当前点击按钮中的delete_id属性
  8. var $this = $(this); // 给this设置一个变量
  9. swal({
  10. title: "确定要删除吗?",
  11. text: "要想好哦!",
  12. icon: "warning",
  13. buttons: true,
  14. dangerMode: true,
  15. })
  16. .then((willDelete) => {
  17. if (willDelete) {
  18. // 向后端发送ajax请求
  19. $.ajax({
  20. url:'/del_book/',
  21. type:'post',
  22. data:{'delete_id':delete_id},
  23. success:function (args) {
  24. // js代码自动刷新
  25. $this.parent().parent().remove();
  26. {#window.location.reload();#}
  27. swal(args, {
  28. icon: "success",
  29. }
  30. );
  31. }
  32. })
  33. } else {
  34. swal("取消成功!");
  35. }
  36. });
  37. })
  38. </script>
  39. {% endblock %}

第三方模块:https://sweetalert.js.org

ajax如何发送文件数据

  1. <body>
  2. 文件数据<input type="file" id="i1">
  3. 普通数据<input type="text" id="i2">
  4. 普通数据<input type="text" id="i3">
  5. <button id="b1">提交</button>
  6. <script>
  7. $('#b1').on('click',function () {
  8. // 先获取输入框中用户的数据
  9. {#let i1Val = $('#i1').val();#}
  10. {#let i2Val = $('#i2').val();#}
  11. {#let i3Val = $('#i3').val();#}
  12. // ajax发送携带文件数据的请求,需要借助与内置对象FormData
  13. // 1.生成一个FormData对象
  14. let formDdatObj = new FormData();
  15. // 2.向该对象中添加数据(支持普通数据和文件数据)
  16. formDdatObj.append('name',$('#i2').val());
  17. formDdatObj.append('pwd',$('#i3').val());
  18. // 获取文件数据有固定的语法格式
  19. formDdatObj.append('file',$('#i1')[0].files[0]);
  20. // 发送ajax请求
  21. $.ajax({
  22. url:'/ab_file/',
  23. type:'post',
  24. // 发送文件需要额外配置的两个参数
  25. contentType:false,
  26. processData:false,
  27. data:formDdatObj,
  28. success:function () {
  29. }
  30. })
  31. })
  32. </script>
  33. </body>

dataType参数

  1. """前后端交互 如果采用的是ajax 那么后端的返回值应该使用字典(json格式)"""
  2. # 结论:
  3. 1、当后端采用HttpResponse返回json格式数据到ajax异步回调函数默认情况下需要我们自己做反序列化JSON.parse如果不想自己处理可以添加dataType:"JSON"
  4. 2、如果后端是采用JsonResponse返回json格式数据则无需我们自己处理也不需要添加 # 返回的就是JSON格式数据
  5. 3dataType:"JSON"参数(加了也不影响) # 处理JSON数据最好加上
  6. # 以后推荐加上 增加程序兼容性
  7. <button id="b1">提交</button>
  8. <script>
  9. $('#b1').click(function () {
  10. $.ajax({
  11. url:'/ab_json/',
  12. type:'post',
  13. data:'',
  14. // 自动把后端返回的JSON格式数据序列化
  15. dataType:'JSON',
  16. success:function (args) {
  17. console.log(args);
  18. console.log(typeof args);
  19. // 反序列化
  20. {#let json_obj = JSON.parse(args);#}
  21. {#console.log(json_obj);#}
  22. {#console.log(typeof json_obj);#}
  23. {#console.log(json_obj.code)#}
  24. }
  25. })
  26. })
  27. </script>

序列化模块

  1. 什么意思呢?
  2. 就是我的前端想拿到由ORM得到的数据库里面的一个个用户对象,我的后端想直接将实例化出来的数据对象直接发送给客户端,那么这个时候,就可以用Django给我们提供的序列化方式
  3. def ser(request):
  4. #拿到用户表里面的所有的用户对象
  5. user_list=models.User.objects.all()
  6. #导入内置序列化模块
  7. from django.core import serializers
  8. #调用该模块下的方法,第一个参数是你想以什么样的方式序列化你的数据
  9. ret=serializers.serialize('json',user_list)
  10. return HttpResponse(ret)
  11. # 拿到所有数据对象去JSON格式化网站格式化
  12. 格式化网站:https://www.bejson.com/

批量插入数据

  1. # 批量插入数据有三种方法:
  2. 一、循环插入 # 不推荐此法 效率极低
  3. 循环创建十万本书籍数据
  4. def ab_bc(request):
  5. for i in range(100000): # 不推荐此法 效率极低
  6. models.Book.objects.create(title='第%s本书'%i)
  7. 二、利用生成器插入 # 如果对象很多的情况下 比较浪费空间
  8. def ab_bc(request):
  9. new_obj_list = []
  10. for i in range(100000):
  11. 仅仅是用类产生了对象 并没有操作数据库
  12. book_obj = models.Book(title='第%s本新的书'%i)
  13. 三、bulk_create方法: # 推荐使用
  14. def ab_bc(request):
  15. new_obj_iter = (models.Book(title='第%s本新的书'%i) for i in range(100000))
  16. # 批量插入
  17. models.Book.objects.bulk_create(new_obj_iter) # 用bulk_create方法批量插入
  18. # 查询所有
  19. data_queryset = models.Book.objects.all()
  20. return render(request,'ab_bc.html',locals())
  21. '''使用bulk_create方法可以大大减少操作的时间'''

分页器思路

  1. 前提准备:先使用bulk_create方法创建1000条书籍数据
  2. 完成分页器需要考虑的几个问题
  3. 1.需要数据的总量
  4. 2.需要定义每页展示多少条
  5. 3.需要计算总共需要多少页
  6. 4.需要推导出几个核心参数的数学关系
  7. 5.需要后端生成html代码
  8. # 可以切片来完成
  9. 思路:
  10. 1.获取用户想访问的页码,如果没有默认展示第一页,并做类型转换
  11. 2.设置每页展示多少条数据,并设置切片的初始位置和终止位置
  12. 3.根据设置的几个参数找数学规律,并把规律复制给切片的初始位置和终止位置的变量
  13. 4.这一步就可以根据浏览器的?page=10,来实现展示多少页
  14. 5.pager.html加上bookstrap分页样式
  15. 6.通过内置方法divmod,使所有的数据 / 每页展示多少条 == 总页数
  16. # divmod(100,10) 返回(10,0) 100/10 返回整数和余数
  17. 7.利用for循环渲染前端页面,并指定添加页码传入前端,前端引用变量名
  18. 8.后端传输数据到前端必须转义,转义后所有的页码都显示在浏览器中。 # 但是页码太多,要求只展示11个页码
  19. 9.通过for循环来控制展示多少页码 # for i in range(current_page-5, current_page+6):
  20. 规律:
  21. """
  22. 下面需要研究current_page、per_page_num、start_page、end_page四个参数之间的数据关系
  23. per_page_num = 10
  24. current_page start_page end_page
  25. 1 0 10
  26. 2 10 20
  27. 3 20 30
  28. 4 30 40
  29. per_page_num = 5
  30. current_page start_page end_page
  31. 1 0 5
  32. 2 5 10
  33. 3 10 15
  34. 4 15 20
  35. 可以很明显的看出规律
  36. start_page = (current_page - 1) * per_page_num
  37. end_page = current_page* per_page_num
  38. 设置每页展示10条数据,当页码为1的时候,切片的起始位置为0,终止位置为10。
  39. 页码为2的时候,切片的起始位置为10,终止位置为20。
  40. 依次切片下去,达成每页展示10条数据的效果
  41. """

分页器核心逻辑

views.py

  1. from django.shortcuts import render, HttpResponse
  2. from app01 import models
  3. def pager(request):
  4. # 批量插入1000本书籍记录
  5. # new_obj_iter = (models.Book(title='第%s本书'%i) for i in range(1000)) # 现在并没有走数据库,只是一个生成器表达式
  6. # 批量插入
  7. # models.Book.objects.bulk_create(new_obj_iter)
  8. '*******************************分页器代码实现*****************************************'
  9. # 查询所有数据
  10. all_data = models.Book.objects.all()
  11. # 获取用户想访问的页码,如果没有默认展示第一页
  12. current_page = request.GET.get('page', 1)
  13. try:
  14. current_page = int(current_page) # 做类型转换
  15. except Exception:
  16. current_page = 1
  17. # 设置每页展示10条数据
  18. per_page_num = 10
  19. # 需要对总数据进行切片操作 需要确定切片起始位置和终止位置
  20. start_page = (current_page - 1) * per_page_num # 切片起始位置
  21. end_page = current_page * per_page_num # 切片终止位置
  22. # 通过divmod内置函数计算多少页
  23. all_page_num, more = divmod(len(all_data), per_page_num) # 用divmod方法,使所有的数据除于每页展示多少条
  24. if more:
  25. all_page_num += 1 # more是余数,余数有值就给总页数加一
  26. # print(all_page_num) # 总页数700
  27. # 渲染前端页面
  28. html = ''
  29. xxx = current_page
  30. if current_page < 6:
  31. xxx = 6
  32. # 用当前页-5和当前页+6来控制显示的页码
  33. for i in range(xxx-5, xxx+6):
  34. # 当前页和访问页一致,会有高亮显示
  35. if current_page == i:
  36. # 生成页码
  37. tmp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
  38. else:
  39. tmp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
  40. html += tmp # 把页码都放入html里,在前端引用即可
  41. # 查询所有
  42. data_request = all_data[start_page:end_page]
  43. return render(request, 'pager.html', locals())

pager.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  7. <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  8. </head>
  9. <body>
  10. <!--把后端传入的数据展示到浏览器上-->
  11. {% for book_obj in data_request %}
  12. <p>{{ book_obj.title }}</p>
  13. {% endfor %}
  14. <!--分页样式-->
  15. <nav aria-label="Page navigation">
  16. <ul class="pagination">
  17. <li>
  18. <a href="?page=1" aria-label="Previous">
  19. <span aria-hidden="true">首页</span>
  20. </a>
  21. </li>
  22. # 引用并创建页码
  23. {{ html | safe }}
  24. <li>
  25. <a href="?page={{ all_page_num }}" aria-label="Next">
  26. <span aria-hidden="true">尾页</span>
  27. </a>
  28. </li>
  29. </ul>
  30. </nav>
  31. </body>
  32. </html>

day11 序列化组件、批量出入、自定义分页器的更多相关文章

  1. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  2. Django序列化组件与数据批量操作与简单使用Forms组件

    目录 SweetAlert前端插件 Django自带的序列化组件 批量数据操作 分页器与推导流程 Forms组件之创建 Forms组件之数据校验 Forms组件之渲染标签 Forms组件之信息展示 S ...

  3. DRF 序列化组件 序列化的两种方式 反序列化 反序列化的校验

    序列化组件 django自带的有序列化组件不过不可控不建议使用(了解) from django.core import serializers class Books(APIView): def ge ...

  4. Django序列化组件Serializers详解

    本文主要系统性的讲解django rest framwork 序列化组件的使用,基本看完可以解决工作中序列化90%的问题,写作参考官方文档https://www.django-rest-framewo ...

  5. Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07

    目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...

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

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

  7. 分页器,序列化组件,bulk_create,choices字段

    分页器 <!--前端--> {% for book in page_queryset %} <p>{{ book.title }}</p> {% endfor %} ...

  8. Django中数据传输编码格式、ajax发送json数据、ajax发送文件、django序列化组件、ajax结合sweetalert做二次弹窗、批量增加数据

    前后端传输数据的编码格式(contentType) 提交post请求的两种方式: form表单 ajax请求 前后端传输数据的编码格式 urlencoded formdata(form表单里的) ja ...

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

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

随机推荐

  1. namaspace之pid namespace

    认识Namespace namespace 是 Linux 内核用来隔离内核资源的方式.通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的 ...

  2. 05 | 箭头函数 | es6

    基本用法 参数列表)=> {函数体} var f = v => v; 上面的箭头函数等同于: var f = function(v) { return v; }; 如果箭头函数不需要参数或 ...

  3. js分支语句

    一.逻辑分支(选择结构,分支结构) 其实今天的课程才算开始涉及到逻辑 程序的三大结构 顺序结构 - 每天 代码逐行执行,一行一行自上而下执行 分支结构 有选择了,十字路口的选择,只能选择一个,如果.. ...

  4. java中将double保留两位小数,将double保留两位小数并转换成String

    将Double类型的数据保留2位小数: Double a = 3.566; BigDecimal bd = new BigDecimal(a); Double d = bd.setScale(2, B ...

  5. FZU ICPC 2020 寒假训练 1

    B - Sum Problem In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n. Input The i ...

  6. SpringCloud微服务实战——搭建企业级开发框架(十六):集成Sentinel高可用流量管理框架【自定义返回消息】

    Sentinel限流之后,默认的响应消息为Blocked by Sentinel (flow limiting),对于系统整体功能提示来说并不统一,参考我们前面设置的统一响应及异常处理方式,返回相同的 ...

  7. python-内置函数(搭配lambda使用)

    目录 常用的内置函数 需要注意的知识点: enumerate()函数 map()函数 zip()函数 filter()函数 reduce()函数 sum()函数 max()/ min()函数 sort ...

  8. Spring Boot 2.6.0正式发布:默认禁止循环依赖、增强Docker镜像构建...

    昨天,Spring官方正式发布了Spring Boot今年最后一个特性版本:2.6.0 同时,也宣布了2.4.x版本的终结. 那么这个新版本又带来了哪些新特性呢?下面就一起跟着DD来看看吧! 重要特性 ...

  9. Dapr初体验之服务调用

    初次理解服务调用 在微服务中,有一个难点就是:如果你想使用各个服务组件,你就得知道不同服务的地址和端口,也就是服务发现. 在传统应用我们是怎么做的?就是在web项目里配置上api地址,如下: 在一个w ...

  10. redis可以设置过期key回调实现延时队列

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...