码迷,mamicode.com
首页 > Web开发 > 详细

文件上传

时间:2019-05-28 18:35:39      阅读:358      评论:0      收藏:0      [点我收藏+]

标签:trace   inpu   open   object   onclick   group   修改   eve   length   

使用 AdminLTE 2 网站中的 form 表单的代码:https://adminlte.io/themes/AdminLTE/pages/forms/general.html (使用其原先css样式及HTML代码,代码内容经过精简)

 

前端代码:

 

首先:一个带有输入框跟上传按钮的HTML文件(样式图如下:)

技术图片

技术图片
1 <div class="form-group">
2     <label for="thumbnail-form">缩略图</label>
3     <div class="input-group">
4         <input type="text" class="form-control" id="thumbnail-form" name="thumbnail">
5         <span class="input-group-btn">
6             <input type="file" class="btn btn-default" id="thumbnail-btn" value="上传文件">
7         </span>
8     </div>
9 </div>
View Code

使用 input标签 , type=file 时显示的样式;

 

将上图修改为下图的样式,使其更美观;

技术图片

技术图片
 1 <div class="form-group">
 2     <label for="thumbnail-form">缩略图</label>
 3     <div class="input-group">
 4         <input type="text" class="form-control" id="thumbnail-form" name="thumbnail">
 5         <span class="input-group-btn">
 6             <label class="btn btn-default btn-file">
 7                 上传图片<input  hidden type="file" class="btn btn-default" id="thumbnail-btn">
 8             </label>
 9         </span>
10     </div>
11 </div>
View Code

id = "thumbnail-form":输入框的ID;

id = "thumbnail-btn":作为隐藏起来的 file标签 文件的一个按钮ID;

使用 label标签,其中 for 中的值等于 input 的ID相当于点击“缩略图”时会默认点击下方输入框;点击“上传图片”会默认点击“type=file”的标签;二者之间存在关联;

使用 hidden 将 file标签 隐藏起来,使“上传图片”的字体将其覆盖;

 

使用js文件监听其上传时的点击事件;

技术图片
 1 function News() {
 2 
 3 }
 4 
 5 News.prototype.run = function () {
 6     var self = this;
 7     self.ListenUploadFileEvent();
 8 };
 9 
10 // 监听文件上传的事件;
11 News.prototype.ListenUploadFileEvent = function () {
12     var uploadBtn = $(‘#thumbnail-btn‘);
13     uploadBtn.change(function () {
14         var file = uploadBtn[0].files[0];
15         var formData = new FormData();
16         formData.append(‘file‘, file);
17         xfzajax.post({
18             ‘url‘: ‘/cms/upload_file/‘,
19             ‘data‘: formData,
20             ‘processData‘: false,
21             ‘contentType‘: false,
22             ‘success‘: function (result) {
23                 if (result[‘code‘] === 200){
24                     var url = result[‘data‘][‘url‘];
25                     var thumbnailInput = $(‘#thumbnail-form‘);
26                     thumbnailInput.val(url);
27                 }
28             }
29         })
30     });
31 };
32 
33 $(function () {
34     var news = new News();
35     news.run();
36 });
View Code

 

change:用来监听进入上传文件选定文件后点击打开按钮的事件,此处不能使用 click 点击事件;

因为 uploadBtn 得到的是一个集合,不是一个单一的对象。所以 var file = uploadBtn[0].files[0]; 中的 uploadBtn[0] 用来获取其中的唯一一个按钮,与其存储的所有文件中的第一个文件。

formData:用来存储文件;

 formData.append(‘file‘, file); :引号中的字段名需与后台通过 ‘get’ 获取文件填写的字段名保持一致;

然后通过ajax请求发送给后端服务器,跳转的 url 及其数据 formData,后两个 false  为告知上层 jquery-3.3.1.min.js 文件不对该文件的数据再次进行处理或添加其它内容,以及成功或者失败的返回内容(失败内容定义在ajax文件中);

在后端中得到的url完整路径,调用 ‘restful’ 中的 ‘result’ 函数,再将获取的 ‘url’ 的值给到前端输入框中显示。

 

ajax代码

技术图片
 1 //static:xfzajax.js
 2 function getCookie(name) {
 3     var cookieValue = null;
 4     if (document.cookie && document.cookie !== ‘‘) {
 5         var cookies = document.cookie.split(‘;‘);
 6         for (var i = 0; i < cookies.length; i++) {
 7             var cookie = jQuery.trim(cookies[i]);
 8             // Does this cookie string begin with the name we want?
 9             if (cookie.substring(0, name.length + 1) === (name + ‘=‘)) {
10                 cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
11                 break;
12             }
13         }
14     }
15     return cookieValue;
16 }
17 
18 var xfzajax = {
19     ‘get‘: function (args) {
20         args[‘method‘] = ‘get‘;
21         this.ajax(args);
22     },
23     ‘post‘: function (args) {
24         args[‘method‘] = ‘post‘;
25         this._ajaxSetup();
26         this.ajax(args);
27     },
28     ‘ajax‘: function (args) {
29         var success = args[‘success‘];
30         args[‘success‘] = function (result) {
31             if (result[‘code‘] === 200) {
32                 if (success) {
33                     success(result)
34                 }
35             } else {
36                 var messageObject = result[‘message‘];
37                 if (typeof messageObject == ‘string‘ || messageObject.constructor === String) {
38                     window.messageBox.showError(messageObject);
39                 } else {
40                     // {"password":[‘密码最大长度不能超过20为!‘,‘xxx‘],"telephone":[‘xx‘,‘x‘]}
41                     for (var key in messageObject) {
42                         var messages = messageObject[key];
43                         var message = messages[0];
44                         window.messageBox.showError(message);
45                     }
46                 }
47                 if(success){
48                     success(result)
49                 }
50             }
51         };
52         args[‘fail‘] = function (error) {
53             console.log(error);
54             window.showError(‘服务器内部错误!‘)
55         };
56         $.ajax(args);
57     },
58     ‘_ajaxSetup‘: function () {
59         $.ajaxSetup({
60             beforeSend: function (xhr, settings) {
61                 if (!/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type) && !this.crossDomain) {
62                     xhr.setRequestHeader("X-CSRFToken", getCookie(‘csrftoken‘));
63                 }
64             }
65         });
66     }
67 };
View Code

 

 

后端代码:

 

settings.py文件的设置:

技术图片
1 # 在末尾添加内容;
2 
3 STATIC_URL = /static/
4 STATICFILES_DIRS = [
5     os.path.join(BASE_DIR,front,dist),
6 ]
7 
8 MEDIA_URL = /media/
9 MEDIA_ROOT = os.path.join(BASE_DIR,media)
View Code

使用MEDIA_ROOTMEDIA_URL,用来指定文件上传后存储的位置,在主目录中新建‘media’文件用来存储内容;

 

文件的映射路径,与前端 ajax 内容中跳转的 url 一致。

技术图片
 1 # 总的url链接;
 2 
 3 from django.urls import path,include
 4 from django.conf.urls.static import static
 5 from django.conf import settings
 6 
 7 urlpatterns = [
 8     path(cms/,include(apps.cms.urls)),
 9 ] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
10 
11 
12 # cms的url:
13 
14 from django.urls import path
15 from . import views
16 
17 app_name = cms
18 
19 urlpatterns = [
20     path(upload_file/,views.upload_file,name=upload_file),
21 ]
View Code

 

视图函数

技术图片
 1 from django.views.decorators.http import require_POST, 
 2 from utils import restful
 3 from django.conf import settings
 4 import os
 5 
 6 
 7 # 文件上传;
 8 @require_POST
 9 def upload_file(request):
10     file = request.FILES.get(file)
11     name = file.name
12     with open(os.path.join(settings.MEDIA_ROOT,name),wb) as fp:
13         for chunk in file.chunks():
14             fp.write(chunk)
15     url = request.build_absolute_uri(settings.MEDIA_URL + name)
16     return restful.result(data={url:url})
View Code

使用 “get” 获取的 “file” 与前端提到 “file” 一致;

使用 build_absolute_uri 可以获取完整的url地址;

 

restful.py文件(简化每个文件代码运行结果的代码量)

技术图片
 1 from django.http import JsonResponse
 2 
 3 class HttpCode(object):
 4     ok = 200            # 正常运行;
 5     paramserror = 400   # 参数错误;
 6     unauth = 401        # 没授权;
 7     methoderror = 405   # 请求方法错误;
 8     servererror = 500   # 服务器内部错误;
 9 
10 def result(code=HttpCode.ok,message=‘‘,data=None,kwargs=None):
11     json_dict = {code:code,message:message,data:data}
12     if kwargs and isinstance(kwargs,dict) and kwargs.keys():
13         json_dict.update(kwargs)
14     return JsonResponse(json_dict)
15 
16 def ok():
17     return result()
18 
19 def params_error(message=‘‘,data=None):
20     return result(code=HttpCode.paramserror,message=message,data=data)
21 
22 def unauth(message=‘‘,data=None):
23     return result(code=HttpCode.unauth,message=message,data=data)
24 
25 def method_error(message=‘‘,data=None):
26     return result(code=HttpCode.methoderror,message=message,data=data)
27 
28 def server_error(message=‘‘,data=‘‘):
29     return result(code=HttpCode.servererror,message=message,data=data)
View Code

 

文件上传

标签:trace   inpu   open   object   onclick   group   修改   eve   length   

原文地址:https://www.cnblogs.com/liqiongming/p/10939252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!