Django中的文件的上传的几种方式


Posted in Python onJuly 23, 2018

PS:这段时间有点不在状态,刚刚找回那个状态,那么我们继续曾经的梦想

今天我们来补充一下文件的上传的几种方式:

首先我们先补充的一个知识点:

一、请求头ContentType:

ContentType 指的是请求体的编码类型,常见的类型共有三种:

1、application/x-www-form-urlencoded

这应该是最常见的POST提交数据的方式。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=duoduo&age=22

2、multipart/form-data

这又是一个常见的POST数据提交的方式。我们使用表单上传文件时,必须让<form>表单的enctype 等于multipart/form-data

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="user"

duoduo
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以  --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往  rfc1867 查看。

这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也 只支持这两种方式 (通过 <form> 元素的  enctype 属性指定,默认为  application/x-www-form-urlencoded 。其实  enctype 还支持  text/plain ,不过用得非常少)。

随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

3 、application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

二、基于form表单的文件上传

模块部分

<form action="" method="post" enctype="multipart/form-data">
   用户名 <input type="text" name="user">
   头像 <input type="file" name="avatar">
  <input type="submit">
</form>

视图部分

def index(request):
  print(request.body)  # 原始的请求体数据
  print(request.GET)  # GET请求数据
  print(request.POST)  # POST请求数据
  print(request.FILES) # 上传的文件数据


  return render(request,"index.html")

三、基于Ajax的文件上传

模块

<form>
   用户名 <input type="text" id="user">
   头像 <input type="file" id="avatar">
   <input type="button" id="ajax-submit" value="ajax-submit">
</form>

<script>

  $("#ajax-submit").click(function(){
    var formdata=new FormData();
    formdata.append("user",$("#user").val());
    formdata.append("avatar_img",$("#avatar")[0].files[0]);
    $.ajax({

      url:"",
      type:"post",
      data:formdata,
      processData: false ,  // 不处理数据
      contentType: false,  // 不设置内容类型

      success:function(data){
        console.log(data)
      }
    })

  })

</script>

视图

def index(request):

  if request.is_ajax():

    print(request.body)  # 原始的请求体数据
    print(request.GET)  # GET请求数据
    print(request.POST)  # POST请求数据
    print(request.FILES) # 上传的文件数据

    return HttpResponse("ok")


  return render(request,"index.html")

检查浏览器的请求头:

Content - Type : multipart / form - data; boundary = - - - - WebKitFormBoundaryaWl9k5ZMiTAzx3FT

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python常用内置函数总结
Feb 08 Python
详解Python中__str__和__repr__方法的区别
Apr 17 Python
Python中对元组和列表按条件进行排序的方法示例
Nov 10 Python
Python 爬虫爬取指定博客的所有文章
Feb 17 Python
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
对numpy和pandas中数组的合并和拆分详解
Apr 11 Python
python3 selenium 切换窗口的几种方法小结
May 21 Python
python3实现小球转动抽奖小游戏
Apr 15 Python
Python random模块制作简易的四位数验证码
Feb 01 Python
关于Python字符串显示u...的解决方式
Mar 06 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
Mar 03 Python
pytorch中[..., 0]的用法说明
May 20 Python
flask中的wtforms使用方法
Jul 21 #Python
详解flask表单提交的两种方式
Jul 21 #Python
python实现周期方波信号频谱图
Jul 21 #Python
Flask-Mail用法实例分析
Jul 21 #Python
python实现傅里叶级数展开的实现
Jul 21 #Python
Python实现快速傅里叶变换的方法(FFT)
Jul 21 #Python
Python实现获取本地及远程图片大小的方法示例
Jul 21 #Python
You might like
PHP伪静态页面函数附使用方法
2008/06/20 PHP
ajax php 实现写入数据库
2009/09/02 PHP
php初始化对象和析构函数的简单实例
2014/03/11 PHP
一些常用弹出窗口/拖放/异步文件上传等实用代码
2013/01/06 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
深入理解js promise chain
2016/05/05 Javascript
angularjs实现文字上下无缝滚动特效代码
2016/09/04 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
AngularJS中$apply方法和$watch方法用法总结
2016/12/13 Javascript
jquery dialog获取焦点的方法
2017/02/09 Javascript
jQuery事件_动力节点Java学院整理
2017/07/05 jQuery
Vue中自定义全局组件的实现方法
2017/12/08 Javascript
详解vue移动端日期选择组件
2018/02/22 Javascript
js图数据结构处理 迪杰斯特拉算法代码实例
2019/09/11 Javascript
python中函数传参详解
2016/07/03 Python
Python实现计算两个时间之间相差天数的方法
2017/05/10 Python
Python实现的基数排序算法原理与用法实例分析
2017/11/23 Python
Python编程求质数实例代码
2018/01/31 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
2019/12/11 Python
如何利用python检测图片是否包含二维码
2020/10/15 Python
python tqdm库的使用
2020/11/30 Python
HTML5自定义data-* data(obj)属性和jquery的data()方法的使用
2012/12/13 HTML / CSS
美国在线自行车商店:Jenson USA
2018/05/22 全球购物
Carmen Sol官网:购买果冻鞋、手袋和配件
2021/01/01 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
信息专业个人的自我评价
2013/12/27 职场文书
事业单位辞职信范文
2014/01/19 职场文书
2014党员民主评议个人总结
2014/09/10 职场文书
2015年人事工作总结范文
2015/04/09 职场文书
妇产科护理心得体会
2016/01/22 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
CSS极坐标的实例代码
2021/06/03 HTML / CSS
php去除deprecated的实例方法
2021/11/17 PHP
python保存图片的四个常用方法
2022/02/28 Python