Django之AJAX文件上传

  文件上传:

·         一般文件上传都是采用post请求方式,get请求携带的数据有限,有post请求的数据放在请求体中,大小不受约束,但是在djangopost请求中要注意csrf(防跨站伪造请求)认证机制;

·         文件上传使用的是multipart/form-data数据格式传输,在使用from表单时需要指定属性enctype="multipart/form-data";在使用ajax时要设置参数:processData: false,contentType: false,文件对象数据的获取需要通过js操作标签DOM对象的files属性取值获取($('#file')[0].files[0]单个文件),同时data数据使用FormData对象。在后端django将文件对象(类似文件句柄)保存在请求对象的request.FILES字典中。

·         在实际应用中,可以通过js代码操作DOM对象的files文件数组,获取到当前上传文件对象,判断文件格式和大小

 

form表单上传文件:

  upload.html 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
 6     <title>upload</title>
 7 </head>
 8 <body>
 9 <!--form上传文件:form标签必须加上enctype属性,指定内容传输格式-->
10 <div>
11     <form action="{% url 'upload' %}" method="post" enctype="multipart/form-data">
12         {% csrf_token %}
13         用户名:<input type="text" name="username"><br>
14         密码:<input type="password" name="password"><br>
15         上传文件:<input type="file" name="file">
16         <br><input type="submit">
17     </form>
18 </div>
19 </body>
20 </html>

  urls.py 

1 urlpatterns = [
2     url(r'^admin/', admin.site.urls),
3     url(r'^upload/', views.upload,name='upload'),
4 ]

  views.py

 1 # form 表单上传文件:
 2     # form页面需要指定属性enctype='multipart/form-data'
 3     #后端获取文件用request.FILES
 4  
 5 def upload(request):
 6     if request.method=='GET':
 7         return render(request,'upload.html')
 8     elif request.method=='POST':
 9         name=request.POST.get('username')
10         psd=request.POST.get('password')
11  
12         # 文件获取用FILES,获取的file_obj类似文件句柄
13         file_obj=request.FILES.get('file')#文件对象
14         file_name = file_obj.name   #文件名
15  
16         # print('>>>>',file_obj,type(file_obj))
17         # print(file_name)
18         
19         #下载写入文件
20         file_path=os.path.join(settings.BASE_DIR,'upload_files',file_name)
21         with open(file_path,'wb')as f:
22             # (1)文件过大不宜使用
23             '''
24             f.write(file_obj.read())
25             '''
26             # (2)每次读取以\r\n为界,数据长度不固定,没有\r\n数据会很大,不宜使用
27             '''
28             for data in  file_obj:
29                 f.write(data)
30             '''
31             #(3)chunks()默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器
32             for chunk in file_obj.chunks():
33                 f.write(chunk)
34                 
35         return HttpResponse('form上传文件')
36  

 

AJAX上传文件:

  upload.html 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
 6     <title>upload</title>
 7 </head>
 8 <body>
 9 <!--ajax上传文件-->
10 <div>
11     {% csrf_token %}
12     用户名:<input type="text" id="username"><br>
13     密码:<input type="password" id="password"><br>
14     上传文件:<input type="file" id="file"><br>
15     <input type="button" id="submit" value="ajax上传文件">
16 </div>
17 </body>
18 <script>
19     $(function () {
20         $('#submit').click(function () {
21             //ajax上传文件必须通过FormData对象传输数据
22             var formdata = new FormData();
23  
24             var username = $('#username').val();
25             var psd = $('#password').val();
26             var csrf_data = $('input[name=csrfmiddlewaretoken]').val();
27             //获取上传文件对象(文件句柄):定位对象,转成DOM对象,取值(文件对象列表)
28             var file = $('#file')[0].files[0];
29  
30             formdata.append('username', username);
31             formdata.append('psd', psd);
32             formdata.append('csrfmiddlewaretoken', csrf_data);//csrf认证的键是固定的
33             formdata.append('file', file);
34  
35             $.ajax({
36                 url: "{% url 'upload' %}",
37                 type: 'post',
38                 data: formdata,
39                 processData: false,//不处理数据
40                 contentType: false,//不设置内容类型,按原格式传输
41                 success: function (response) {
42                     alert(response)
43                 }
44             })
45         })
46     })
47 </script>
48 </html>

urls.py 

1 urlpatterns = [
2     url(r'^admin/', admin.site.urls),
3     url(r'^upload/', views.upload,name='upload'),
4 ]

  views.py 

 1 # ajax上传文件
 2 def  upload(request):
 3     if request.method=='GET':
 4         return render(request,'upload.html')
 5     elif request.method=='POST':
 6         name = request.POST.get('username')
 7         psd = request.POST.get('password')
 8         file_obj = request.FILES.get('file')
 9         file_name = file_obj.name
10         print('>>>>',file_name)
11         # 拼接绝对路径
12         file_path = os.path.join(settings.BASE_DIR, 'upload_files', file_name)
13         with open(file_path, 'wb')as f:
14             for chunk in file_obj.chunks():#chunks()每次读取数据默认我64k
15                 f.write(chunk)
16         return HttpResponse('ajax上传文件')

 

posted @ 2019-07-21 19:40  笑得好美  阅读(544)  评论(0编辑  收藏