shop_platform - 上傳圖片

賣家上架商品時,可以展示商品圖片。表單原本只能填寫圖片網址。

現在要改成可以直接上傳圖片。


form 表單可以上傳圖片

前端

  • form 標籤屬性加上 enctype="multipart/form-data"

    若沒有加的話,enctype 預設使用 application/x-www-form-urlencoded,這樣的話:

    後端只收得到檔案名稱:request.form.get('field_name') 是檔案名稱

    收不到檔案內容:request.files.get('field_name') 是 None

  • input 標籤,改成 type="file",前端防呆加上 accept=".jpg,.jpge,.png,.gif"

後端

  • 驗證檔案副檔名

  • 驗證檔案大小


將圖片存在伺服器

後端收到的檔案,資料型態是 werkzeug.datastructures.FileStorage,可以用 save 方法,把檔案存到指定檔案,目前是存在 static/product_images/ 資料夾。

為了避免不同使用者,不約而同上傳同樣名稱的檔案,我用 uuid 作為新的檔案名稱,再加上副檔名。

前端會用 /static/product_images/<string:filename> 這個網址請求圖片資源。

目前圖片的網址,透露了後端是用什麼資料夾結構儲存圖片資源。但路由和真正的檔案位置其實是可以分開的,設定好路由,在路由中帶入檔名,然後用 flask.send_from_directory 就可以指定從哪個資料夾取出檔案,這樣一來,網址就不會暴露檔案位置了。

commit: feat: user can upload product picture


將圖片存在 imgur

伺服器目前部署在 heroku 上。因為 heroku 的免費方案,有 the maximum slug size is 500 MB 的限制,所以要把圖片都存在伺服器有困難。因此想改成存在 imgur 上。

imgur api 官網推薦的套件是 imgurpython,但已經停止維護,而且功能似乎很多,但我目前只需要上傳圖片、取得圖片網址而已。

搜尋後找到 PyImgurflask-imgur 這兩個套件。PyImgur 最新的 commit 是 2016 年,而且 im.upload_image(PATH, title="Uploaded with PyImgur") 參數要傳入檔案的 path,難道我還得先把檔案存在伺服器,以取得 path 嗎?後來有查到 Upload an uploaded image using PyImgur without saving to a temporary file 這篇教學。flask-imgur 這個套件就方便多了,imgur_handler.send_image(image),image 參數接受的是 werkzeug image object,使用起來更容易,功能只有上傳和刪除照片,符合我的需求,而且最新的 commit 是 2020 年。

所以最後我安裝了 flask-imgur

commit:


參考資料

Comments

Popular posts from this blog

Alpha Camp 全端開發課程學習心得

在 javascript 用 regular expression 為金額加上千位數分隔符號

shop_platform - sqlalchemy.exc.TimeoutError