我们的Django框架或者ajax内部都有一个json的解析机制,可以帮助我们解析json数据,让我们省去使用json.dumps或者JSON.parse等方法进行相应的解析。
-
ajax的js解析机制
views函数:
通过HttpResponse给前端响应数据时,加上一个content_pe=‘application/json‘这样的头部键值对
return HttpResponse(ret_dict_json, content=‘application/json‘)
?
?
ajax:
获得res直接就是一个object对象(字典),因为通过这个头部可以调用ajax的json内部解析机制对其进行解析,省去了JSON.parse(res)这个环节。 -
Django的json解析机制
from django.http import JsonResponse
# JsonResponse 将一个数据内部转化成Json的格式,响应给前端
# 这样我们就省去了json.dumps这个环节
ret_dict = {‘code‘:0, ‘content‘: ‘用户名或者密码错误‘}
return JsonRespone(ret_dict) -
尝试一个列表
html:
{% load static %}
views函数:
def ajax_lx(request):
return render(request, ‘lx.html‘)
def data(request):
l1 = [‘姓名1‘, ‘姓名2‘, ‘姓名3‘]
# 我们通过网络传输数据一般都是字段类型,前端教object类型。
#In order to allow non-dict objects to be serialized set the safe
parameter to False.
return JsonResphonse(l1, safe=False)url:
url(r‘^ajaxlx/‘, views.ajax_lx,name=‘ajaxlx‘),
url(r‘^data/‘, views.data,name=‘data‘),
content-type
这个参数比较重要,这个参数是请求头部信息中,非常重要的参数,这个参数是标明请求参数的数据类型。
-
content-type = application/x-www-form-urlencoded
我们简称encoded类型,一般前端给后端发送数据(get。post),form、ajax等方式默认一般都是encoded类型。
通过ajax提交数据:
通过form表单提交:
这种类型的原始数据是神样子的?
无论是ajax还是form(无论是get还是post)或者其他方式,只要是encoded类型,原始数据都是:
键=值&键=值&键=值...
为什么浏览器会同意这种格式?
浏览器统一了请求数据的格式,便于后端做归一化处理。
看我们的Django后端:
为什么我们通过request.POST.get(键)或者request.GET.get(键)就可以获取该值?
就是因为Django的内部解析器帮助我们做了请求数据的解析:
举例:
Django的内部做了一个这样的判断:
if ‘content_type‘ == ‘application/x-www-form-urlencoded‘:
?
‘‘‘uname=taibai&pwd=123&csrfmiddlewaretoken=oTRcxqSxLGSygOSaMrqyiakOXJIgbM
CBVAESFZ1dqK8ttsHL9maoI9wzLEyfYcaI
‘‘‘
通过&分割,然后在通过等号分割,然后构建到request.POST或者request.GET中,最终我们可以通过get方法获取到对应值。
-
content_type = application/json
Django框架默认不认可这种类型,这就意味着,如果我们与其他的一些程序员或者一些语言写的项目对接数据,这就叫做数据接口,一般这种数据接口都是使用这种数据类型。content_type = application/json类型
验证一下:
这样我们就构建了以application/json的类型的json数据,发送到Django框架的后端。
后端默认取不到对应的值,返回的是None
只能通过:
request.get_full_path() # 获取原始数据
这样我们只能自己完成数据的分割以及获取
我们通过request.META获取conten_type内容,判断如果是application/json类型我们自己在后端对request.get_full_path()进行数据切割,从而获取数据。但是这样给我们增加了开发难度,降低开发效率。这种情况下,有一个第三方模块:*前后端分离的模块,djangorestframework
-
content_type = mutipart/form-data类型
给Django后端发送的请求数据为文件(文本、图片、视频、音频等等),是这种类型,
Django内部解析器可以帮我们解析。
(下面综合文件上传一起)
文件上传
-
form表单
def form_upload(request):
if request.method == ‘GET‘:
return render(request, ‘formupload.html‘)
else:
# print(request.POST)
‘‘‘
<QueryDict: {‘csrfmiddlewaretoken‘:
[‘8FUYSNC9tTfsVpGzHSJlz7s7Lkko1U12FmHE0mLP8Xvn83va4NtbZ6ESzfanOkz9‘],
‘head_pic‘: [‘barry.png‘],
‘ID‘: [‘1232321321321321‘]}>
‘‘‘
# print(request.POST.get(‘ID‘))
# ret = request.POST.get(‘head_pic‘) # 获取了?件的?件名
# print(ret, type(ret))
# file = request.FILES # <MultiValueDict: {}>
# 为什么是空?因为from表单没有规定enctype属性
# < MultiValueDict: {‘head_pic‘: [ < InMemoryUploadedFile: barry.png(image / png) >]} >
# 这个文件数据是一个迭代器,类似于文件的文件句柄
# print(file)
# file_obj = request.FILES.get(‘head_pic‘)
# print(file_obj) # 返回的是名字 因为__str__返回的是名字
# print(file_obj.name) # 获取的是名字
file_obj = request.FILES.get(‘head_pic‘)
from ajac_online import settings
import os
img_path = os.path.join(settings.BASE_DIR,‘statics‘,‘img‘)
# 方式1:
# with open(os.path.join(img_path, file_obj.name), mode=‘wb‘) as fp:
# for line in file_obj:
# 默认按照行去循环,以换行符/r/n为循环节点
# fp.write(line)
# 方式2:
with open(os.path.join(img_path, file_obj.name), mode=‘wb‘) as fp:
for chunk in file_obj.chunks():
f1.write(chunk)
return redirect(‘formupload‘)
?
<!DOCTYPE html>
<html lang="zh-CN">
?
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
</head>
?
<body>
<h1>form表单?件上传</h1>
<form action="" method="post" enctype="multipart/form-data">
{# 这个属性就是规定的content_type类型 #}
{% csrf_token %}
头像:<input type="file" name="head_pic">
<p></p>
身份证:<input type="text" name="ID">
<p></p>