flask 文件上傳頁面(flask 21)

基于登錄表單辰狡,flask 20

支持多文件上傳

upload

app.py

from flask import Flask,flash,redirect,render_template,
url_for,session,send_from_directory,request
import os
import uuid
from flask_wtf.csrf import validate_csrf
from wtforms import ValidationError
from form import LoginForm,UploadForm,MultiUploadForm

app = Flask(name)
app.secret_key = os.getenv('SECRET_KEY', 'secret string')
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True

Custom config

app.config['UPLOAD_PATH'] = os.path.join(app.root_path, 'uploads')
app.config['ALLOWED_EXTENSIONS'] = ['png', 'jpg', 'jpeg', 'gif']
app.config['MAX_CONTENT_LENGTH'] = 3 * 1024 * 1024 # 3Mb
def random_filename(filename):
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename
@app.route('/uploads/<path:filename>')
def get_file(filename):
return send_from_directory(app.config['UPLOAD_PATH'], filename)
@app.route('/uploaded-images')
def show_images():
return render_template('uploaded.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload():
form = UploadForm()
if form.validate_on_submit():
f = form.photo.data
filename = random_filename(f.filename)
f.save(os.path.join(app.config['UPLOAD_PATH'], filename))
flash('Upload success.')
session['filenames'] = [filename]
return redirect(url_for('show_images'))
return render_template('upload.html', form=form)
def allowed_file(filename):
return '.' in filename and
filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
@app.route('/multi-upload', methods=['GET', 'POST'])
def multi_upload():
form = MultiUploadForm()

if request.method == 'POST':
    filenames = []

    # check csrf token
    try:
        validate_csrf(form.csrf_token.data)
    except ValidationError:
        flash('CSRF token error.')
        return redirect(url_for('multi_upload'))

    # check if the post request has the file part
    if 'photo' not in request.files:
        flash('This field is required.')
        return redirect(url_for('multi_upload'))

    for f in request.files.getlist('photo'):
        # if user does not select file, browser also
        # submit a empty part without filename
        # if f.filename == '':
        #     flash('No selected file.')
        #    return redirect(url_for('multi_upload'))
        # check the file extension
        if f and allowed_file(f.filename):
            filename = random_filename(f.filename)
            f.save(os.path.join(
                app.config['UPLOAD_PATH'], filename
            ))
            filenames.append(filename)
        else:
            flash('Invalid file type.')
            return redirect(url_for('multi_upload'))
    flash('Upload success.')
    session['filenames'] = filenames
    return redirect(url_for('show_images'))
return render_template('upload.html', form=form)

form.py

from flask_wtf.file import FileField, FileRequired, FileAllowed

class UploadForm(FlaskForm):
photo = FileField('Upload Image', validators=[FileRequired(), FileAllowed(['jpg', 'jpeg', 'png', 'gif'],message="必須是圖片類型")])
submit = SubmitField()
class MultiUploadForm(FlaskForm):
photo = MultipleFileField('Upload Image', validators=[DataRequired()])
submit = SubmitField()

templates/macros.html

{% macro form_field(field) %}
{{ field.label }}

{{ field(**kwargs) }}

{% if field.errors -%}
{% for error in field.errors -%}
<small class="error">{{ error }}</small>

{%- endfor %}
{%- endif %}
{% endmacro %}

templates/upload.html

<!DOCTYPE html>
{% extends 'base.html' %}
{% from 'macros.html' import form_field %}

{% block content %}
<h2>File Upload Form</h2>

<form method="post" enctype="multipart/form-data">
{{ form.csrf_token }}
{{ form_field(form.photo) }}
{{ form.submit }}
</form>
{% endblock %}

templates/uploaded.html

{% extends 'base.html' %}
{% from 'macros.html' import form_field %}

{% block title %}Home{% endblock %}

{% block content %}
{% if session.filenames %}
{% for filename in session.filenames %}
<a href="{{ url_for('get_file', filename=filename) }}" target="_blank">
<img src="{{ url_for('get_file', filename=filename) }}">
</a>
{% endfor %}
{% endif %}
{% endblock %}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市辛萍,隨后出現(xiàn)的幾起案子遇骑,更是在濱河造成了極大的恐慌卖毁,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件落萎,死亡現(xiàn)場離奇詭異亥啦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)练链,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門翔脱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人媒鼓,你說我怎么就攤上這事届吁。” “怎么了绿鸣?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵疚沐,是天一觀的道長。 經(jīng)常有香客問我潮模,道長亮蛔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任擎厢,我火速辦了婚禮究流,結(jié)果婚禮上辣吃,老公的妹妹穿的比我還像新娘。我一直安慰自己芬探,他們只是感情好神得,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著偷仿,像睡著了一般哩簿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炎疆,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天卡骂,我揣著相機(jī)與錄音,去河邊找鬼形入。 笑死全跨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亿遂。 我是一名探鬼主播浓若,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛇数!你這毒婦竟也來了挪钓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耳舅,失蹤者是張志新(化名)和其女友劉穎碌上,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浦徊,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡馏予,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盔性。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霞丧。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖冕香,靈堂內(nèi)的尸體忽然破棺而出蛹尝,到底是詐尸還是另有隱情,我是刑警寧澤悉尾,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布突那,位于F島的核電站,受9級特大地震影響构眯,放射性物質(zhì)發(fā)生泄漏愕难。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望务漩。 院中可真熱鬧,春花似錦它褪、人聲如沸饵骨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽居触。三九已至,卻和暖如春老赤,著一層夾襖步出監(jiān)牢的瞬間轮洋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工抬旺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留弊予,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓开财,卻偏偏與公主長得像汉柒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子责鳍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容