1:導入element
1
2
3
4
5
6
|
<!-- 引入樣式 --> < link rel = "stylesheet" href = "https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel = "external nofollow" > <!-- 引入組件庫 --> <!-- 引入Vue --> < script src = "https://unpkg.com/element-ui/lib/index.js" ></ script > |
2:前端文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
css: .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } html: {% comment %} 上傳圖片 {% endcomment %} < div id = "profile" > < h1 style = "text-align: center" >更新社團封面</ h1 > < div id = "app" style = "text-align: center" > < el-upload :data = "datas" // 攜帶的參數 :headers = "headers" // 請求頭 name = "image" {% comment %} 后端接收的參數名 {% endcomment %} class = "avatar-uploader" action = "/show/images/" {% comment %} 上傳路由地址 {% endcomment %} :show-file-list = "false" :before-upload = "beforeAvatarUpload" > {% comment %} 上傳文件之前的鉤子,參數為上傳的文件 {% endcomment %} < img v-if = "imageUrl" :src = "imageUrl" class = "avatar" > < i v-else class = "el-icon-plus avatar-uploader-icon" ></ i > </ el-upload > </ div > </ div > {% comment %} 上傳圖片 {% endcomment %} # JS: < script > var Main = { data() { return { headers:{}, // 請求頭是個對象 datas:{}, // 對象 imageUrl: '' }; }, create(){ this.headers.authenticate = sessionStorage.getItem('token') // 設置請求頭帶token this.datas.data = "userHead" // 設置請求參數 } methods: { handleAvatarSuccess(res, file) { this.imageUrl = URL.createObjectURL(file.raw); console.log("imageUrl",this.imageUrl) }, beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg'; const isLt2M = file.size / 1024 / 1024 < 2 ; if (!isJPG) { this.$message.error('上傳頭像圖片只能是 JPG 格式!'); } if (!isLt2M) { this.$message.error('上傳頭像圖片大小不能超過 2MB!'); } return isJPG && isLt2M; } } } var Ctor = Vue .extend(Main) new Ctor().$mount('#app') </script> |
3:后端文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
路由: # 預覽圖片url("show/images/$", add_image.Image.as_view()), py文件: from rest_framework.views import APIView from SocietyPlat import settings from django.shortcuts import render, redirect, HttpResponse from Databases import models from django.http import JsonResponse import os # 獲取相對路徑 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class Image(APIView): def post( self , request): # 接收文件 file_obj = request.FILES.get( 'image' , None ) style = requetst.data.get( 'data' ) # 用戶名 # username = str(request.data.get("username")) username = "Wang" print ( "file_obj" ,file_obj.name) # 判斷是否存在文件夾 head_path = BASE_DIR + "\\media\\{}\\head" . format (username).replace( " " ,"") print ( "head_path" ,head_path) # 如果沒有就創建文件路徑 if not os.path.exists(head_path): os.makedirs(head_path) # print("文件名",file_obj.name) # 文件名 name.png # # print("文件二進制",file_obj.read()) # 文件二進制 b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x0 # # print("判斷文件> 2.5M",file_obj.multiple_chunks(chunk_size=None)) # 文件大小 False小于2.5M # # print("文件大小",file_obj.size) # 文件大小 12651 # # print("文件編碼",file_obj.charset) # None # # print("隨文件一起上傳的內容類型標題",file_obj.content_type) # image/png # # print("包含傳遞給content-type標頭的額外參數的字典",file_obj.content_type_extra) # {} # # print("text/content-types提供的utf8字符集編碼",file_obj.charset) # None # # # 圖片后綴 head_suffix = file_obj.name.split( "." )[ 1 ] print ( "圖片后綴" ,head_suffix) # 圖片后綴 png # 儲存路徑 file_path = head_path + "\\{}" . format ( "head." + head_suffix) file_path = file_path.replace( " " ,"") print ( "儲存路徑" , file_path) # C:\Users\user\Desktop\DownTest\media\username\head\head.png # 上傳圖片 with open (file_path, 'wb' ) as f: for chunk in file_obj.chunks(): f.write(chunk) message = {} message[ 'code' ] = 200 # 返回圖片路徑 back_path = '\static\{}\head\{}' . format (username, "head." + head_suffix).replace( " " ,"") message[ 'image' ] = back_path return JsonResponse(message) |
補充知識:django后臺接口處理element-ui的el-upload組件form data類型數據
對于向我這樣一只前端和后端的雙咸魚來說寫一個不了解的接口實在是太難受了,前端不知道在哪找數據,后端又不知道處理什么樣的數據。
現在有這樣一個需求,我需要使用element-ui中的el-upload組件完成一個上傳文件的功能。但是不知道是不是因為我沒有發現,我翻遍了官網都沒有找到這個組件點擊上傳以后發的是什么樣的數據請求。
終于我好像突然想起來瀏覽器的開發者工具可以查看發出的請求
于是我們可以寫這么一個組件來一探究竟:
點擊上傳到服務器以后前臺就會發出請求,我們就可以使用devtool看具體的請求頭等等數據,具體位置在這里:
點擊這個upload,找一找,我們就會發現最下面有一個file
這應該就是我們要上傳的文件。可以看見它是以form data的形式上傳的。
所以我們就可以寫對應的后端接口了。
這里給一個接口的demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
def writeFile(filePath, file ): with open (filePath, "wb" ) as f: if file .multiple_chunks(): for content in file .chunks(): f.write(content) else : data = file .read() ###.decode('utf-8') f.write(data) def uploadFile(request): if request.method = = "POST" : fileDict = request.FILES.items() # 獲取上傳的文件,如果沒有文件,則默認為None if not fileDict: return JsonResponse({ 'msg' : 'no file upload' }) for (k, v) in fileDict: print ( "dic[%s]=%s" % (k,v)) fileData = request.FILES.getlist(k) for file in fileData: fileName = file ._get_name() filePath = os.path.join(settings.TEMP_FILE_PATH, fileName) print ( 'filepath = [%s]' % filePath) try : writeFile(filePath, file ) except : return JsonResponse({ 'msg' : 'file write failed' }) return JsonResponse({ 'msg' : 'success' }) |
另外想要在前端獲取后端返回的請求的話可以使用on-success、on-error、on-exceed這幾個鉤子函數,具體可以在element ui的官網找到
以上這篇Django后端分離 使用element-ui文件上傳方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/wanghong1994/p/12913091.html