Django:学习笔记(8)——文件上传

Django:学习笔记(8)——文件上传

文件上传前端处理

本模块使用到的前端Ajax库为Axio,其地址为GitHub官网

关于文件上传

上传文件就是把客户端的文件发送给服务器端。

在常见情况(不包含文件上传)下,我们POST请求Content-Type是application/x-www-form-urlencoded,这意味着消息内容会经过URL编码,就像在GET请求时URL里的QueryString那样。txt1=hello&txt2=world。为了支持表单上传,我们第一个要设置的请求的Content-Type,即为multipart/form-data,以支持客户端向服务器发送二进制数据。

一个常见的请求上传格式大概是这样的:

基于表单进行上传

我们首先构建一个简易的文件上传表单,这里面有几个需要注意的地方:

  • 在form中,我们添加了enctype="multipart/form-data" 这条属性,enctype属性规定了在发送到服务器之前应该如何对表单数据进行编码

  • action="upload"> 指明了服务器接受文件的地址。

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form name="uploadForm" method="POST" enctype="multipart/form-data" action="upload"> <table> <tr> <td>UserName</td> <td><input type="text" name="username"></td> </tr> <tr> <td>upload1</td> <td><input type="file" name="file"></td> </tr> <tr><td><input type="submit" name="submit" value="上传"></td></tr> </table> </form> </body> </html>

然后,再点击上传按钮后,服务器将会接收到上传请求。

补充:

在HTML5中,通过在input元素中引入多个multiple属性,使得多个文件的上传变得更加简单,下面均可使一个上传框支持多个文件上传。

1<input type="file" name="fieldName" multiple/> 2<input type="file" name="fieldName" multiple="multiple"/> 3<input type="file" name="fieldName" multiple=""/>

基于FormData进行上传

FormData对象用以将数据编译成键值对,以便用XMLHttpRequest****来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,则会使用表单的**submit()**方法来发送数据,从而,发送数据与传统表单具有同样形式。

简单来说就是,我们完全用JavaScript代码来拼写表单数据,如下:

1var formData = new FormData(); 2 3//普通字段 4formData.append("username", "Groucho"); 5formData.append("accountnum", 123456); //数字123456会被立即转换成字符串 "123456" 6 7// 文件:基于<input type=‘file’/> 8formData.append("userfile", fileInputElement.files[0]); 9 10// 文件:Blob 对象 11var content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的正文... 12var blob = new Blob([content], { type: "text/xml"}); 13formData.append("webmasterfile", blob);

接着,我们就可以使用axios,来上传数据,此处需要注意的是,我们需要进行请求头的设置:'Content-Type': 'multipart-/form-data'

1//构造表头 2let config = { 3 headers: { 4 'Content-Type': 'multipart-/form-data' 5 } 6 } 7 8axios.post("//127.0.0.1:8000/web/cam", formData, config) 9 .then((response) => {})) 10 .catch((error) =>{});

到这里,前端的处理就完成了。

Django处理文件上传请求

简单模式

所谓简单模式,就是我们不使用Django的高级特性,单单从文件的接收、保存与读取考虑。首先,我们知道文件数据会保存在request.FILES中。

我们通过,request.FILES['文件名'],来获取指定的文件,然后将其保存。

1def SaveImage(image): 2 imgname = settings.MEDIA_ROOT+"/"+image.name 3 with open(imgname,'wb') as f: 4 for fimg in image.chunks(): 5 f.write(fimg) 6 return imgname

函数最后,返回imgname表示图片的地址,我们可以使用读取命令,来读取图片数据。

基于表单模型

首先,我们需要创建一个表单模型,其中file会映射请求中名为file的文件数据。

1# forms.py 2from django import forms 3 4class UploadFileForm(forms.Form): 5 title = forms.CharField(max_length=50) 6 file = forms.FileField()

然后,编写视图,其中一定要注意,需要将两个参数传递给表单模型UploadFileForm(request.POST, request.FILES) ,之后就可以进行表单验证了。最后交由处理函数来处理上传的文件。

1# views.py 2 3from django.http import HttpResponseRedirect 4from django.shortcuts import render 5from .forms import UploadFileForm 6 7# 另外写一个处理上传过来的文件的方法,并在这里导入 8from somewhere import handle_uploaded_file 9 10def upload_file(request): 11 if request.method == 'POST': 12 form = UploadFileForm(request.POST, request.FILES) # 注意获取数据的方式 13 if form.is_valid(): 14 handle_uploaded_file(request.FILES['file']) 15 return HttpResponseRedirect('/success/url/') 16 else: 17 form = UploadFileForm() 18 return render(request, 'upload.html', {'form': form})

注意:

request.FILES只有在请求方法为POST,并且提交请求的<form>具有enctype="multipart/form-data"属性时才有效。 否则,request.FILES将为空。

我们可以调用调用form.save(),这样文件对象会保存在相应的FileField的upload_to参数指定的地方。

还有一个需要注意的地方,我们可以直接把文件对象直接从request.FILES赋值给模型:

1from .models import ModelWithFileField 2... 3instance = ModelWithFileField(file_field=request.FILES['file'])
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )