19。Django(内部解析、conten-type、文件上传)

内部解析机制

我们的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 %}
    <!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, initialscale=1">
       <title>Bootstrap 101 Template</title>
    </head>
    ?
    <body>
       <h3>欢迎来到ajaxlx??</h3>
       <ul>
       </ul>
    </body>
    <script src="{% static ‘jQuery.js‘ %}"></script>
    <script>
       $.ajax({
           url: "{% url ‘data‘ %}",
           type: ‘get‘,
           success: function (res) {
              {#console.log(res, typeof res)# }
              {#var li = ‘<li>‘ + res + ‘</li>‘# }
               $.each(res, function (k, v) {
                   var li = ‘<li>‘ + v + ‘</li>‘;
                   $(‘ul‘).append(li)
              })
          }
      })
    </script>
    ?
    </html>

    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提交数据:

    19。Django(内部解析、conten-type、文件上传)

     

     

    通过form表单提交:

    19。Django(内部解析、conten-type、文件上传)

     

     

    这种类型的原始数据是神样子的?

    19。Django(内部解析、conten-type、文件上传)

     

     

    无论是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类型

    验证一下:

    19。Django(内部解析、conten-type、文件上传)

     

     

    这样我们就构建了以application/json的类型的json数据,发送到Django框架的后端。

    后端默认取不到对应的值,返回的是None

    19。Django(内部解析、conten-type、文件上传)

     

     

    只能通过:

    request.get_full_path()  # 获取原始数据

    这样我们只能自己完成数据的分割以及获取

    19。Django(内部解析、conten-type、文件上传)

    我们通过request.META获取conten_type内容,判断如果是application/json类型我们自己在后端对request.get_full_path()进行数据切割,从而获取数据。但是这样给我们增加了开发难度,降低开发效率。这种情况下,有一个第三方模块:*前后端分离的模块,djangorestframework

     

 

  • content_type = mutipart/form-data类型

    给Django后端发送的请求数据为文件(文本、图片、视频、音频等等),是这种类型,

    Django内部解析器可以帮我们解析。

    (下面综合文件上传一起)

 

文件上传

  • form表单

    19。Django(内部解析、conten-type、文件上传)

     

     

    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>
           <input
上一篇:URL跳转


下一篇:Android自定义圆形ProgressBar