目標
解決原本圖片路徑只有純文字的情況:
後端
views.py
- 要得知是「哪一個產品」需要更新圖片,所以需傳入
product_id
用 request.FILES.get('image')
取得上傳的圖片檔案
- 先不用規範
permission_classes
,這樣前端才不用在 config
額外取 token
1 2 3 4 5 6 7 8
| @api_view(['POST']) def uploadImage(request): data = request.data product_id = data['product_id'] product = Product.objects.get(id=product_id) product.image = request.FILES.get('image') product.save() return Response('圖片上傳成功!')
|
urls.py
1
| path('upload/', views.uploadProductImage,name="product_image_upload"),
|
前端
產品編輯前端頁面
- 上傳
Handler
函式必須得是 async
,因為要等待上傳完成後再執行下一步
<Form.File
相關寫法已在 react-bootstrap V5
版本以上被棄用,改用 <Form.Control type='file' />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const uploadImageHandler = async (e) => { console.log(e.target.value); };
return( ... <Form.Group controlId='image' className='mb-3'> <Form.Label>產品圖片</Form.Label> <Form.Control required type='text' placeholder='請輸入產品圖片' value={image} onChange={(e) => setImage(e.target.value)}></Form.Control> <Form.Control type='file' onChange={uploadImageHandler} /> </Form.Group> {ImageUploading && <Loader />} )
|
逐步慢慢測試,先查看上傳檔案後,主控台是否有印出檔案名稱
確定有擷取到檔案後,用 e.target.files[0];
取得檔案陣列中的第一個檔案,並宣告一個 FormData
物件,將檔案名稱、產品 ID 一併帶入 FormData
物件傳給後端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const uploadImageHandler = async (e) => { const file = e.target.files[0]; const formData = new FormData();
formData.append("product_image", file); formData.append("product_id", productID); try { const { data } = await axios.post("/api/products/upload/", formData); setImage(data); setImageUploading(false); } catch (error) { setImageUploading(false); } };
|
- 使用
FormData
作為請求體時,Axios
會自動檢測並設置適當的 Content-Type
,不需要自己寫 config
設定,若後端有額外規定 permission_classes
就需要在config
設定 token
/api/products/upload/
的路徑一定要跟後端 urls.py
設定的一模一樣,原本在 upload
這少加了 /
,一直報 405 Error
完成後,應就能看到產品成功更換圖片,去專案的 static
資料夾下,也能看到上傳的新圖片檔
若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~
留言版