day 55 Ajax
-
XML也是一门标记语言
-
该语言应用场景
- 书写配置文件
- 可以写前端页面(odoo框架 erp)
-
每家公司都会有属于自己的内部管理软件
专门用来开发企业内部管理软件,框架 odoo
odoo框架内部功能依赖于python2
-
-
ajax 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页信息(可以极大的提高用户体验)
-
ajax是基于js书写的,我们可以基于JQuery
-
语法结构
ajax基本语法结构 $.ajax({ url:'', // 数据提交的后端地址 不写就是往当前页面提交 也可以写后缀 也可以写全称 跟actions一样 type:'post', // 提交方式 默认是get请求 data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 提交的数据 success:function (data) { // 形参data就是异步提交之后后端返回结果 $('#d3').val(data) // 回调机制需要做的事情 } }) ## 一旦使用了ajax,事件触发的后端返回值就是与data进行交互而不是浏览器
-
标签请求方式
- a标签href参数 get请求
- form表单 get/post
- ajax get/post
-
ajaxget请求数据urlencoded格式 url?xxx=ooo&zzz=yyy
-
前后端传输数据编码格式
-
前后端交互是一个数据编码格式,针对不同的数据后端会进行不同的分类,
- request.POST()
- request.FILES()
-
常用的三种编码格式
- urlencoded
- formdata
- application/json
-
form 表单发送数据的编码格式
-
# form表单发送数据的编码格式 Content-Type: application/x-www-form-urlencoded 1.form表单默认的编码方式是urlencoded # urlencoded所对应的数据格式 username=jason&password=123 # django后端针对urlencoded数据 会自动解析并且帮你封装到request.POST中 2.form表单发送文件 编码格式 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhjKCHQHDmcE62iMQ # 针对formdata格式的数据 你在浏览器上是无法查看到 # django后端只要你的数据满足urlencoded格式 username=jason&password=123 # 就会自动帮你解析到request.POST中 # 如果你是一个文件对象django后端也会自动识别帮你放到request.FILES中 3.form表单无法发送json格式的数据 你要想法 你只能借助于ajax
-
ajax发送数据的编码格式
-
urlencoded
- ajax默认的编码格式
-
formdata
-
application/json
- django在接受到json格式的数据时不会做任何处理,需要自己进行手动处理
$('#d1').click(function () { $.ajax({ url:'', type:'post', contentType:'application/json', # 1.注意点1 指定编码格式 data:JSON.stringify({'username':'jason','password':'123'}), # 2.注意点2 转换为json格式 success:function (data) { alert(123) } }) }) dumps stringify loads parse
Ajax如何传输文件数据(******) 借助于内置对象 new 该对象即可以携带文件数据 同样也支持普通的键值对 $('#d1').click(function () { // 先生成一个内置对象 var MyFormData = new FormData(); // 1. 先添加普通的键值 MyFormData.append('username','jason'); // 添加了一组普通的简直对 MyFormData.append('password','123'); // 2. 添加文件数据 MyFormData.append('myfile',$('#d2')[0].files[0]); // 如何获取input框中文件对象$('#d1')[0].files[0] $.ajax({ url:'', type:'post', data:MyFormData, # 1 // 发送文件必须要指定的两个参数 contentType:false, // 不适用任何编码 MyFormData对象内部自带编码 django后端能够识别 # 2 processData:false, // 不要处理数据 # 3 success:function (data) { } }) }) 序列化 drf django restframework from app01 import models from django.core import serializers # 序列化目的 将数据整合成一个大字典形式 方便数据的交互 def zzz(request): user_queryset = models.User.objects.all() # [{username:...,password:...,hobby:...,},{},{},{}] # user_list = [] # for data in user_queryset: # user_list.append( # {'username':data.username, # 'password':data.password, # 'gender':data.get_gender_display(), # # } # ) res = serializers.serialize('json',user_queryset) return HttpResponse(res)
-
-
-
ajax结合sweetalert使用
-
sweetalert是一个弹窗组件,用来优化原生的alter
-
语法结构
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}"> <script src="{% static 'dist/sweetalert.min.js' %}"></script> 需要下载到静态文件中再导入 <script> $('.c2').click(function () { 绑定到对应的按钮上 {#var $btn = $(this);#} 此处放从sweetalert拷贝修改的代码 }) </script>
-
-
批量插入数据bull_create()
obj_list = [] for i in range(1000): obj_list.append(model.Book(title=f'{i}')) models.Book.objects.bull_create(obj_list)
-
分页
- 自定义分页器
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: 最多显示的页码个数 用法: queryset = model.objects.all() page_obj = Pagination(current_page,all_count) page_data = queryset[page_obj.start:page_obj.end] 获取数据用page_data而不再使用原始的queryset 获取前端分页样式用page_obj.page_html """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num # 总页码 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 如果总页码 < 11个: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 总页码 > 11 else: # 当前页如果<=页面上最多显示11/2个页码 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 当前页大于5 else: # 页码翻到最后 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_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)