AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即便用Javascript语言与服务器进行异步交互,传输的数据为XML(固然,传输的数据不仅是XML)。前端
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。其实就是基于js写的一个功能模块而已python
因为原生js书写ajax较为繁琐 因此咱们直接学jQuery封装号的ajax模块操做ajax
AJAX 最大的优势是:异步提交,局部刷新数据库
在不从新加载整个页面的状况下,能够与服务器交换数据并更新部分网页内容。(这一特色给用户的感觉是在不知不觉中完成请求和响应过程)
AJAX 不须要任何浏览器插件,但须要用户容许JavaScript在浏览器上执行。django
同步交互:任务提交以后原地等待任务的返回结果 进程表现上来讲 阻塞 异步交互:任务提交以后不须要原地等待返回结果 直接执行下一行代码 进程表现上来讲 非阻塞 任务的结果经过异步回调机制 callback()
案例:用户名在时时和后端交互,可是页面没有刷新。用户体验更好编程
前端与后端的交互方式有:json
1.浏览器窗口输入url回车 GET 2.a标签href属性填写url点击 GET 3.form表单 GET/POST 4.Ajax GET/POST
小案例:后端
初识ajax 案例:页面上有三个input框 一个按钮 用户在前两个框中输入数字 点击按钮保证页面不刷新的状况下将数据发到后端作计算 将计算好的结果再发给前端展现到第三个input框中
效果:浏览器
def index(request): if request.method == 'POST': i1 = request.POST.get('i1') i2 = request.POST.get('i2') # i1 和 i2 是字符串类型 须要先作类型转换 i3 = int(i1) + int(i2) return HttpResponse(i3) return render(request,'index.html')
ajax基本语法结构 // ajax基本语法 $.ajax({ // 1.到底朝哪一个后端提交数据 url:'', // 控制数据的提交路径 有三种写法 跟form表单的action属性一致 type:'post', // 2.指定当前请求方式 data:{'i1':$('#i1').val(),'i2':$('#i2').val()}, // 3.提交的数据 // 4.ajax是异步提交 因此须要给一个回调函数来处理返回的结果 success:function (data) { // data就是异步提交的返回结果 // 将异步回调的结果经过DOM操做渲染到第三个input框中 $('#i3').val(data) } })
urlencoded formdata application/json
form表单默认是urlencoded编码格式传输数据 urlencoded数据格式: username=jason&password=123 django后端针对该格式的数据 会自动解析并帮你打包到request.POST中 formdata数据格式: django后端针对符合urlencoded编码格式数据(普通键值对)仍是统一解析到request.POST中 而针对formdata文件数据就会自动解析放到request.FILES中 application/json django后端针对json格式数据 并不会作任何的处理 而是直接放在request.body中
ajax默认的也是urlencoded编码格式 先后端数据交互 编码格式与数据格式必定要一致 不能骗人家!!! ,声明什么编码格式,就用传什么格式
$('#d2').on('click',function () { $.ajax({ url:'', type:'post', contentType:'application/json', // 修改content-Type参数 data:JSON.stringify({'username':'jason','password':123}), // 将数据序列化成json格式字符串 success:function (data) { alert(data) } }) })
前端不会处理json格式的数据,而是直接塞进request.body中。咱们本身处理json格式数据,拿到的是二进制json
咱们本身处理,解码,反序列化
json.loads可以自动解码而且序列化
def ab_ct(request): if request.method == 'POST': # 本身处理json格式数据 json_bytes = request.body # 扩展 json.loads可以自动解码并序列化 json_dict = json.loads(json_bytes) print(json_dict,type(json_dict)) print(request.POST) print(request.FILES) return render(request,'ab_ct.html')
须要借助内置对象FormData
这个对象能够传普通键值对,也能够传文件
jQ new关键字生成对象
ajax发送文件(******) 内置对象FormData 即发普通键值对也发文件 // ajax发送文件数据 须要借助于内置对象 $('#d3').click(function () { // 1 须要先生成一个内置对象 var myFormData = new FormData(); // 2 传普通键值对 当普通键值对较多的时候 咱们能够利用for循环来添加 myFormData.append('username','jason'); myFormData.append('password',123); // 3 传文件 myFormData.append('myfile',$('#i1')[0].files[0]); // 获取input框内部用户上传的文件对象 // 发送ajax请求 $.ajax({ url:'', type:'post', data:myFormData, // 发送formdata对象须要指定两个关键性的参数 processData:false, // 让浏览器不要对你的数据进行任何的操做 contentType:false, // 不要使用任何编码格式 对象formdata自带编码格式而且django可以识别该对象 success:function (data) { alert(data) } }) })
借助serializers帮你自动完成序列化
from app01 import models from django.core import serializers def ab_se(request): user_queryset = models.Userinfo.objects.all() user_list = [] for user_obj in user_queryset: user_list.append({ 'username':user_obj.username, 'password':user_obj.password, 'gender':user_obj.get_gender_display(), }) res = json.dumps(user_list) res = serializers.serialize('json',user_queryset) # 序列化 return HttpResponse(res)
须要大家掌握的仅仅是如何使用便可 推导思路能够稍做了解 后端 current_page = request.GET.get('page', 1) all_count = book_queryset.count() # 1 现生成一个自定义分页器类对象 page_obj = Pagination(current_page=current_page,all_count=all_count,pager_count=9) # 2 针对真实的queryset数据进行切片操做 page_queryset = book_queryset[page_obj.start:page_obj.end] return render(request,'ab_bc.html',locals()) 前端 {% for book_obj in page_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} {{ page_obj.page_html|safe }}
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)