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

今日内容详细

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

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

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

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

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

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

{% block js %}
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script>
var $btn = $('.c1'); // 找到c1标签
// 绑定点击事件
$btn.on('click',function (){
var delete_id = $(this).attr('delete_id'); // 拿当前点击按钮中的delete_id属性
var $this = $(this); // 给this设置一个变量
swal({
title: "确定要删除吗?",
text: "要想好哦!",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
// 向后端发送ajax请求
$.ajax({
url:'/del_book/',
type:'post',
data:{'delete_id':delete_id},
success:function (args) {
// js代码自动刷新
$this.parent().parent().remove();
{#window.location.reload();#}
swal(args, {
icon: "success",
}
);
}
})
} else {
swal("取消成功!");
}
});
})
</script>
{% endblock %}

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

ajax如何发送文件数据

<body>
文件数据<input type="file" id="i1">
普通数据<input type="text" id="i2">
普通数据<input type="text" id="i3">
<button id="b1">提交</button>
<script>
$('#b1').on('click',function () {
// 先获取输入框中用户的数据
{#let i1Val = $('#i1').val();#}
{#let i2Val = $('#i2').val();#}
{#let i3Val = $('#i3').val();#}
// ajax发送携带文件数据的请求,需要借助与内置对象FormData
// 1.生成一个FormData对象
let formDdatObj = new FormData();
// 2.向该对象中添加数据(支持普通数据和文件数据)
formDdatObj.append('name',$('#i2').val());
formDdatObj.append('pwd',$('#i3').val());
// 获取文件数据有固定的语法格式
formDdatObj.append('file',$('#i1')[0].files[0]); // 发送ajax请求
$.ajax({
url:'/ab_file/',
type:'post',
// 发送文件需要额外配置的两个参数
contentType:false,
processData:false,
data:formDdatObj,
success:function () {
}
})
})
</script>
</body>

dataType参数

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

序列化模块

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

批量插入数据

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

分页器思路

前提准备:先使用bulk_create方法创建1000条书籍数据

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

分页器核心逻辑

views.py

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

pager.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!--把后端传入的数据展示到浏览器上-->
{% for book_obj in data_request %}
<p>{{ book_obj.title }}</p>
{% endfor %} <!--分页样式-->
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="?page=1" aria-label="Previous">
<span aria-hidden="true">首页</span>
</a>
</li>
# 引用并创建页码
{{ html | safe }}
<li>
<a href="?page={{ all_page_num }}" aria-label="Next">
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</nav>
</body>
</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. python读取、写入txt文本内容

    转载:https://blog.csdn.net/qq_37828488/article/details/100024924 python常用的读取文件函数有三种read().readline().r ...

  2. Typecho部署小破站

    写在前面 以前利用 Github Page + Hexo框架 + Next主题搭建过静态博客,没错就是那个黑白色系的网页!但是体验并不是很好,一来本身是静态网页,页面内容要修改都需要在本地修改完上传到 ...

  3. LeetCode Weekly Contest 266

    第一题 题解:模拟题 class Solution { public: int countVowelSubstrings(string w) { int n = w.length(); int i = ...

  4. 3D 穿梭效果?使用 CSS 轻松搞定

    背景 周末在家习惯性登陆 Apex,准备玩几盘.在登陆加速器的过程中,发现加速器到期了. 我一直用的腾讯网游加速器,然而点击充值按钮,提示最近客户端升级改造,暂不支持充值(这个操作把我震惊了~).只能 ...

  5. 手撸一个IOC容器

    IoC 什么是IoC? IoC是Inversion of Control(控制反转)的简称,注意它是一个技术思想.描述的是对象创建.管理的事情. 传统开发方式:比如类A依赖类B,往往会在类A里面new ...

  6. Mybatis:插入数据返回自增主键

    使用Mybatis作为工具连接MySQL,要求在插入数据之后返回自增主键 一开始也很迷惑,Mybatis使用insert之后,成功返回的是1,失败会报错或返回0,主键去哪找来 后来知道Mybatis可 ...

  7. 【Mysql】表锁 行锁 记录锁 间隙锁

    Mysql中的锁 基于锁的属性分类:共享锁.排他锁. 基于锁的状态分类:意向共享锁.意向排它锁 根据锁的粒度分类:全局锁.页锁.表级锁.行锁(记录锁.间隙锁.和临键锁),实际上的锁就这些,上面两种分类 ...

  8. Python 中的反转字符串:reversed()、切片等

    摘要:以相反的顺序反转和处理字符串可能是编程中的一项常见任务.Python 提供了一组工具和技术,可以帮助您快速有效地执行字符串反转. 本文分享自华为云社区<Python 中的反转字符串:rev ...

  9. Excel 读取写入数据库

    // Excel 读取写入数据库 // 3.8版本的poi  4.0 可以不用写  parseCell  这个方法,可以直接赋值 STRING 类型 import org.apache.poi.hss ...

  10. 印象最深的一个bug:sessionStorage缓存在移动端失效

    无bug,不程序:作为程序员的我,不是修bug就是在写bug的路上. 移动端sessionStorage缓存失效是我"印象最深的一个bug"之一,为啥呢,因为这个问题导致我加班到很 ...