【Ajax简介】
1 Ajax功能就8个字: 异步提交,局部刷新 2 3 ajax不是一门新的技术并且有很多版本 我们目前学习的是jQuery版本(版本无所谓 本质一样就可以) 4 5 AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程) 6 7 AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。 8 9 10 =================== 11 12 (使用Ajax的时候一定要导入JQuery模块) 13 14 前端HTML文件引入这段代码 15 16 <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
。
。
【基本语法】
需求:
需求:做一个页面,该页面上有3个input框,用户在前两个input框里面输入一些数字,点击提交按钮后,在第3个框里面展示出来结果!,
要求点了按钮后将两个数据发送给后端,
后端计算好后,再将结果发送给前端的第3个input框,然后在框里面展示出来!!!点击提交按钮后页面不准刷新!
1 views.py 2 3 def ab_ajax(request): 4 if request.method == 'POST': 5 # print(request.POST) # 数据朝哪里拿 6 # 做+运算 7 i1 = int(request.POST.get('i1')) 8 i2 = int(request.POST.get('i2')) 9 i3 = int(i1 + i2) 10 print(i3) 11 # 返回字典操作,需要序列化,import json 12 # d = {'code': 100, 'msg': 'i3', } 13 d = {'code': 100, 'msg': 666, } 14 # return HttpResponse(i3) 15 # return HttpResponse(json.dumps(d)) # {"code": 100, "msg": "i3"} 报错 16 # 换成下列方法from django.http import JsonResponse 17 return JsonResponse(d) # object 18 return render(request, 'index.html') 19 20 21 --------------------------------------------------- 22 index.html 23 24 <!DOCTYPE html> 25 <html lang="en"> 26 <head> 27 <meta charset="UTF-8"> 28 <title>Title</title> 29 <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"> 30 {# <script src="JQ.js"></script>#} 31 <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> 32 <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> # 必须引入 33 34 </head> 35 <body> 36 <input type="text" id="d1">+ 37 <input type="text" id="d2">= 38 <input type="text" id="d3"> 39 <p> 40 <button id="btn">点我</button> 41 </p> 42 43 <script> 44 //给按钮绑定一个点击事件 45 $('#btn').click(function () { 46 //朝后端发送ajax请求 47 $.ajax({ 48 //1.指定朝哪个后端发送ajax请求 49 //不写就是朝当前地址提交/ 50 url: '', 51 52 //2.指定提交方式,不指定默认get请求 53 type: 'post', 54 55 //3.指定提交的数据,不指定默认空 56 //data:{'username':'jason', 'password':123}, 拿到的是一个对象, 57 data: {'i1':$('#d1').val(), 'i2':$('#d2').val()}, 58 //指定回调函数,当请求成功后调用这个函数,(异步回调机制) 59 60 //4.回调函数:当请求成功后自动触发这个函数,args接收后端的返回结果 61 {#dataType:true, //会自动帮我们反序列化#} 62 //触发:当后端返回给我们结果的时候自动触发这个函数,args接收后端的返回结果 63 success:function(args){ 64 {#alert(args) //通过DOM操作动态渲染到迪桑Input里面#} 65 {#$('#d3').val(args)#} 66 //看前端字典返回值console是什么类型 67 //string字符串类型,然后反序列化 68 console.log(typeof args) 69 {#JSON.parse(args)#} 70 } 71 }) 72 }) 73 </script> 74 </body> 75 </html>
。
。
【前后端传输数据编码格式】
。
。
【ajax发送json数据格式】
1 ajax发送json数据 2 django针对json格式的数据不会做任何处理 3 json格式的数据会原封不动的封装到request.body中 4 {"username":"jason","age":18} 5 在request.POST中拿不到数据,在request.FILES中拿不到数据, 6 request对象方法补充 7 request.body 8 获取请求体数据,默认是bytes类型 9 10 11 ---------------------------------- 12 urls.py 13 14 path('json_ajax/', views.json_ajax) 15 16 17 views.py 18 19 def json_ajax(request): 20 print(request.POST) # 拿不到数据 21 print(request.FILES) # 也拿不到数据 22 print(request.body) # 拿到数据 b'{"username":"jason","age":18}' 23 # 拿到的是二进制格式,需要我们自己处理 24 if request.method == 'POST': 25 json_bytes = request.body 26 # 方式一 27 # json_str = json_bytes.decode('utf-8') 28 # json_dict= json.loads(json_str) 29 30 # json.loads内部可以直接自动解码再反序列化 31 # 方式二 32 json_dict = json.loads(json_bytes) 33 print(json_dict,type(json_dict)) 34 return render(request, 'json_ajax.html') 35 36 =============================== 37 html 38 39 <!DOCTYPE html> 40 <html lang="en"> 41 <head> 42 <meta charset="UTF-8"> 43 <title>Title</title> 44 <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"> 45 {# <script src="JQ.js"></script>#} 46 <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> 47 <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> 48 </head> 49 <body> 50 <button class="btn btn-danger" id="d1">点我</button> 51 <script> 52 $("#d1").click(function () { 53 $.ajax({ 54 url: '', 55 type: 'post', 56 {#data:{'username':'jason','age':18},#} 57 //urlencoded格式如何变成json格式,加下面一段代码(指定编码格式) 58 //检查格式确实是:application/json 59 data: JSON.stringify({'username': 'jason', 'age': 18}), 60 contentType: 'application/json', 61 success: function (args) { 62 } 63 }) 64 }) 65 </script> 66 </body> 67 </html>
。
。
【ajax发送文件】
ajax发送文件需要借助于js内置对象formdata
【django内置序列化组件(drf前身)】
。
。
。
【ajax结合sweetalert进行二次确认】
需要用到的第三方模块网站SweetAlert for Bootstrap (lipis.github.io)
sweetalert模块下载:SweetAlert2 download | SourceForge.net
。
。
。
【批量插入数据】
1 def batch_insert(request): 2 # 先给book插入500条数据 3 for i in range(200): 4 models.Book.objects.create(title='第%s本书'%i) 5 # 再将所有的数据查询并展示到前端页面 6 book_queryset = models.Book.objects.all() 7 8 # 上述方法明显卡顿,慢 9 10 ================================== 11 12 # 批量插入 13 book_obj_list = [] 14 for i in range(100): 15 book_obj = models.Book(title='第%s本书' % i) 16 book_obj_list.append(book_obj) 17 models.Book.objects.bulk_create(book_obj_list) 18 ''' 19 当你想要批量插入数据的时候,使用orm给提供的bulk_create方法,能够大大的减少操作时间 20 ''' 21 book_queryset = models.Book.objects.all() 22 23 =========================== 24 25 # 分页操作,每页展示10条 26 book_list = models.Book.objects.all() 27 # 当前想访问哪一页 28 current_page = request.GET.get('page', 1) # 如果获取不到当前页码,就展示第一页 29 # 数据类型转换 30 try: 31 current_page = int(current_page) 32 except Exception: 33 current_page = 1 34 # 每页展示多少条 35 page_size = 10 36 # 起始位置 37 start = (current_page - 1) * page_size 38 # 终止位置 39 end = current_page * page_size 40 # 动态计算出需要多少页 41 all_count = book_list.count() 42 page_count, more = divmod(all_count, page_size) 43 if more: 44 page_count += 1 45 page_html = '' 46 # 页码做限制 47 xxx = current_page 48 if current_page < 6: 49 current_page = 6 50 for i in range(current_page - 5, current_page + 6): 51 if xxx == i: 52 page_html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i) 53 else: 54 page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i) 55 book_queryset = book_list[start:end] 56 return render(request, 'batch_insert.html', locals())
html页面
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"> 7 <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> 8 <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> 9 {% load static %} 10 <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}"> 11 <script src="{% static 'dist/sweetalert.min.js' %}"></script> 12 </head> 13 <body> 14 {% for book_obj in book_queryset %} 15 <p>{{ book_obj.title }}</p> 16 17 {% endfor %} 18 {# 分页#} 19 <nav aria-label="Page navigation"> 20 <ul class="pagination"> 21 <li> 22 <a href="#" aria-label="Previous"> 23 <span aria-hidden="true">«</span> 24 </a> 25 </li> 26 {{ page_html|safe }} 27 <li> 28 <a href="#" aria-label="Next"> 29 <span aria-hidden="true">»</span> 30 </a> 31 </li> 32 </ul> 33 </nav> 34 </body> 35 </html>
【分页器】
【分页器升级】
当我们需要使用到非dajngo内置的第三方功能或者其他组件代码的时候,
我们一般情况下会创建一个名为utils(工具)文件夹,在该文件夹内对模块进行功能性划分
# 自定义分页器代码:到应用文件下创个others文件夹,然后创个mapage.py文件,把下面的代码丢进去就行了, # 这个分页器写的很好,逻辑判断,一点问题没有,所有情况全部考虑到了!!! class Pagination(object): def __init__(self, current_page, all_count, per_page_num=10, 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 = 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)