Flask Web開發入門(十)之圖片上傳(使用Flask-Upload)

__HelloWorld__發表於2018-01-11

Flask Web開發入門(八)之檔案上傳中,我們探討了Flask框架下的檔案上傳,本章我們將使用Flask外掛Flask-Uploads示例說明的圖片上傳與展現如何實現

開始之前,我們先簡單看下Flask-Uploads原始碼實現:

UploadSet

檔案上傳配置集合,包含三個引數:

  • name:檔案上傳配置集合的名稱,預設files,一般不用修改,只是一個標識,要求數字、字母或兩者組合,滿足isalnum
  • extensions:上傳檔案型別,預設DEFAULTS = TEXT + DOCUMENTS + IMAGES + DATA,包含文字、文件、圖片、CSV、INI、YML等配置檔案
  • default_dest:上傳檔案的預設儲存路徑,我們可以通過app.config[‘UPLOADS_DEFAULT_DEST’]來指定

方法configure_uploads

應用配置好之後,呼叫此方法,掃描上傳配置選項並儲存到我們的應用中,註冊上傳模組。

方法resolve_conflict

解決名字重複問題,如果伺服器上已經存在指定檔名的檔案,那麼Flask-Uploads通過此方法解決檔案儲存時的衝突問題,解決策略:檔名後加_num,num從1開始,之後拿新的名字重新判斷是否存在,如果仍舊存在,再次加1,直至不存在為止

方法實現:

name, ext = os.path.splitext(basename)
        count = 0
        while True:
            count = count + 1
            newname = '%s_%d%s' % (name, count, ext)
            if not os.path.exists(os.path.join(target_folder, newname)):
                return newname

方法呼叫:

        if os.path.exists(os.path.join(target_folder, basename)):
            basename = self.resolve_conflict(target_folder, basename)

示例

簡單分析完Flask-Uploads原始碼實現之後,我們來看下如何通過Flask-Uploads實現圖片上傳與展現

  • 定義基本配置與應用註冊
app.config['UPLOADS_DEFAULT_DEST'] = UPLOAD_PATH
app.config['UPLOADS_DEFAULT_URL'] = 'http://127.0.0.1:9000/'
uploaded_photos = UploadSet()
configure_uploads(app, uploaded_photos)
  • 上傳處理邏輯
# http://flask-uploads.readthedocs.io/en/latest/
@app.route('/flask-upload', methods=['POST'])
def flask_upload():
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            logger.debug('No file part')
            return jsonify({'code': -1, 'filename': '', 'msg': 'No file part'})
        file = request.files['file']
        # if user does not select file, browser also submit a empty part without filename
        if file.filename == '':
            logger.debug('No selected file')
            return jsonify({'code': -1, 'filename': '', 'msg': 'No selected file'})
        else:
            try:
                filename = uploaded_photos.save(file)
                logger.debug('%s url is %s' % (filename, uploaded_photos.url(filename)))
                return jsonify({'code': 0, 'filename': filename, 'msg': uploaded_photos.url(filename)})
            except Exception as e:
                logger.debug('upload file exception: %s' % e)
                return jsonify({'code': -1, 'filename': '', 'msg': 'Error occurred'})
    else:
        return jsonify({'code': -1, 'filename': '', 'msg': 'Method not allowed'})

注意:核心方法即:uploaded_photos.save(file)

  • 前臺程式碼
 var photoUpload = upload.render({
            elem: '#btn_photo'
            , url: '/flask-upload'
            , exts: 'jpg|png|jpeg'
            , size: 5120
            , before: function (obj) {
                obj.preview(function (index, file, result) {
                    $('#photo').attr('src', result);
                    $('#photo').css('width', '300');
                    $('#photo').css('height', '300');
                });
            }
            , done: function (res) {
                if (res.code == 0) {
                    layer.msg(res.filename + '上傳成功!');
                    var href = '<a href="' + res.msg + '" style="color:blue; text-decoration: solid;">' + res.msg + '</a>'
                    $('#txt_photo').html(href)
                } else {
                    return layer.msg('上傳失敗');
                }
            }
            , error: function () {
                var photo = $('#txt_photo');
                photo.html('<span style="color: #FF5722;">上傳失敗</span> <a class="layui-btn layui-btn-mini demo-reload">重試</a>');
                photo.find('#btn_photo').on('click', function () {
                    photoUpload.upload();
                });
            }
        });
  • 實現效果

注意紅色框內的檔名,我連續上傳了三次,那麼第三次檔名後面家了_2

這裡寫圖片描述



原始碼參考:https://github.com/ypmc/flask-sqlalchemy-web

相關文章