目录

一.前后端传输数据的编码格式(contentType)

1.form表单

2.编码格式

3.Ajax

4.代码演示

后端

前端HTML

二.Ajax发送JSON格式数据

1.引入

后端

前端

2.后端

接收到的数据为空

解决办法

3.request方法判断Ajax

4.总结

前端在通过ajax请求发送数据的时候,一定要注参数修改

数据是真正的JSON格式数据

Django后端不会帮我们处理JSON格式数据,需要自己手动处理request.body中的数据

三.Ajax发送文件数据

1.Ajax发送文件数据需要借助js内置对象formdata

前端

后端

发送文件数据的格式

2.结论

Ajax发送文件数据需要利用内置对象FormData

需要指定两个关键性的参数

Django后端能直接自动识别到FormData对象

四.分页

1.前言

2.自定义分页器封装代码

3.后端使用方法

4.前端使用方法


一.前后端传输数据的编码格式(contentType)

主要研究POST请求数据的编码格式

因为GET请求数据就是直接放在url后面的

  • 可以朝后端发送post请求的方式
    • form请求
    • ajax请求

1.form表单

  • 前后端传输数据的格式
    • urlencoded
    • formdata
    • json

2.编码格式

  • form表单默认的编码格式是urlencoded
    • 通过查看请求头中的Content-Type参数
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding:gzip, deflate, brAccept-Language:zh-CN,zh;q=0.9,en;q=0.8Cache-Control:no-cacheConnection:keep-aliveContent-Length:27Content-Type:application/x-www-form-urlencoded
  • 携带数据格式
username=666666&password=66
  • Django后端针对urlencoded编码格式的数据会自动帮我们解析封装到request.POST中
  • 如果编码格式改为formdata,那么针对普通的键值对还是解析到request.POST中,而其他文件格式的数据解析到request.FILES中
  • form表单无法发送json格式数据

3.Ajax

Accept:*/*Accept-Encoding:gzip, deflate, brAccept-Language:zh-CN,zh;q=0.9,en;q=0.8Cache-Control:no-cacheConnection:keep-aliveContent-Length:31Content-Type:application/x-www-form-urlencoded; charset=UTF-8
  • 默认的编码格式是urlencoded
  • 数据格式
username=dream&password=1314521
  • Django后端针对urlencoded编码格式的数据会自动帮我们解析封装到request.POST中—>username = dream&password=123456

4.代码演示

后端

def index(request):if request.method == 'POST':print(request.POST)print(request.FILES)return render(request, 'index.html')

前端HTML

username:

password:

file:

$("#d1").click(function () {$.ajax({url: '',type: 'POST',data: {"username": "dream", "password": 1314521},success: function (args) {},})})

二.Ajax发送JSON格式数据

前后端传输数据的时候一定要保证编码格式数据与真正的数据格式是一致的

1.引入

后端

def ab_json(request):if request.method == 'POST':print(request.POST) #return render(request, 'ab_json.html')

前端

$('#d1').click(function () {$.ajax({url: '',type: 'post',// 前端数据转JSON格式数据 :JSON.stringifydata: JSON.stringify({"username": "dream", "password": 521521}),// 不指定参数,默认就是 urlencodedcontentType: 'application/json',success: function (args) {}})})
  • 请求标头携带的数据格式
    • 已成功转换为JSON格式
{"username":"dream","password":521521}

2.后端

接收到的数据为空

def ab_json(request):if request.method == 'POST':print(request.POST) #return render(request, 'ab_json.html')

Django 针对JSON格式的数据不会做任何处理

针对JSON格式的数据需要自己手动处理

解决办法

def ab_json(request):print(request.is_ajax())# Trueif request.method == 'POST':print(request.POST)# print(request.body)# 返回的是二进制数据 :b'{"username":"dream","password":521521}'# 针对JSON格式的数据需要自己手动处理json_bytes = request.body# (1)方式一:先解码 再转换数据格式json_str = json_bytes.decode('utf-8')json_dict = json.loads(json_str)print(json_dict, type(json_dict))# {'username': 'dream', 'password': 521521} # (2)方式二:json.loads(二进制数据) 内部可以自动解码再反序列化json_dict_loads = json.loads(json_bytes)print(json_dict_loads, type(json_dict_loads))# {'username': 'dream', 'password': 521521} return render(request, 'ab_json.html')

3.request方法判断Ajax

request.is_ajax()

返回当前请求是否是ajax请求,返回布尔值

print(request.is_ajax()) 正常浏览器网址回车提交的是 GET 请求 – 结果是False 当我们发送ajax请求后 – 结果是True

4.总结

前端在通过ajax请求发送数据的时候,一定要注参数修改

// 不指定参数,默认就是 urlencodedcontentType: 'application/json',

数据是真正的JSON格式数据

发送的数据一定要符合JSON格式

或经过JSON序列化再传输

Django后端不会帮我们处理JSON格式数据,需要自己手动处理request.body中的数据

通过Ajax传过来的数据是二进制数据

在request.body中要经过自己的反序列化才能拿到我们想要的数据

三.Ajax发送文件数据

1.Ajax发送文件数据需要借助js内置对象formdata

前端

username:

password:

file:

// 点击按钮向后端发送普通键值对数据和文件数据$("#btn").on('click', function () {// (1)先生成一个内置对象let formDataObj = new FormData();// (2)支持添加普通的键值对formDataObj.append('username', $("#d1").val());formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象formDataObj.append('myfile', $("#d3")[0].files[0]);// (4)基于Ajax,将文件对象发送给后端$.ajax({url: '',type: 'post',// 直接将对象放到data里面即可data: formDataObj,// Ajax发送文件必须添加的两个参数// 不需要使用任何编码 -Django后端能自动识别 formdata 对象contentType: false,// 告诉浏览器不要对我的数据进行任何处理processData: false,success: function (args) {}})})

后端

def ab_file(request):if request.is_ajax():if request.method == 'POST':print('POST::>>', request.POST)# 普通键值对放在了request.POST 中# POST::>> print('FILES::>>', request.FILES)# 文件数据放在了request.FILES 中# FILES::>> <MultiValueDict: {'myfile': []}>return render(request, 'ab_file.html')

发送文件数据的格式

// 点击按钮向后端发送普通键值对数据和文件数据$("#btn").on('click', function () {// (1)先生成一个内置对象let formDataObj = new FormData();// (2)支持添加普通的键值对formDataObj.append('username', $("#d1").val());formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象formDataObj.append('myfile', $("#d3")[0].files[0]);// (4)基于Ajax,将文件对象发送给后端$.ajax({url: '',type: 'post',// 直接将对象放到data里面即可data: formDataObj,// Ajax发送文件必须添加的两个参数// 不需要使用任何编码 -Django后端能自动识别 formdata 对象contentType: false,// 告诉浏览器不要对我的数据进行任何处理processData: false,success: function (args) {}})

2.结论

Ajax发送文件数据需要利用内置对象FormData

// (1)先生成一个内置对象let formDataObj = new FormData();// (2)支持添加普通的键值对formDataObj.append('username', $("#d1").val());formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象formDataObj.append('myfile', $("#d3")[0].files[0]);

需要指定两个关键性的参数

// Ajax发送文件必须添加的两个参数// 不需要使用任何编码 -Django后端能自动识别 formdata 对象contentType: false,// 告诉浏览器不要对我的数据进行任何处理processData: false,
  • Django后端能直接自动识别到FormData对象

    • 将内部的普通键值对自动解析并封装到request.POST中
    • 将内部的文件数据自动解析并封装到request.FILES中
print('POST::>>', request.POST)# 普通键值对放在了request.POST 中# POST::>> print('FILES::>>', request.FILES)# 文件数据放在了request.FILES 中# FILES::>> <MultiValueDict: {'myfile': []}>

四.分页

1.前言

当我们需要使用到非Django内置的第三方模块或者功能组件代码的时候,我们一般情况下会创建一个名为utils的文件夹,在该文件夹中对模块的功能进行划分

注意:样式基于bootstrap,需要引入bootstrap配置

2.自定义分页器封装代码

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:最多显示的页码个数"""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_countself.per_page_num = per_page_num # 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pager self.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2) @propertydef start(self):return (self.current_page - 1) * self.per_page_num @propertydef end(self):return self.current_page * self.per_page_num def page_html(self):# 如果总页码 < 11个:if self.all_pager  11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page  self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1 page_html_list = []# 添加前面的nav和ul标签page_html_list.append('''  ''')return ''.join(page_html_list)

3.后端使用方法

 def get_book(request): book_list = models.Book.objects.all() current_page = request.GET.get("page",1) all_count = book_list.count() page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10) page_queryset = book_list[page_obj.start:page_obj.end] return render(request,'booklist.html',locals())

4.前端使用方法

{% for book in page_queryset %}

{{ book.title }}

{% endfor %}{{ page_obj.page_html|safe }}