首页 > 解决方案 > Flask 表单不允许我上传 TSV 文件

问题描述

我有以下烧瓶应用程序,我希望能够将 TXT 或 TSV 文件上传到表单。问题是,当我尝试上传 TXT 文件时,它可以工作,但是当我尝试上传 TSV 文件时,我收到以下错误:

  File "/Users/cdastmalchi/Desktop/author_script/main.py", line 89, in process_file
    if not places_exist(os.path.join(app.config['UPLOAD_FOLDER'], filename)):
  File "/Users/cdastmalchi/Desktop/author_script/main.py", line 27, in places_exist
    infile = open(filename, 'rU')
IOError: [Errno 2] No such file or directory: './Authors_Template.tsv'

Authors_Template.tsv是从表单下载并进入 的模板文件,Downloads然后我希望用户能够编辑此模板,然后重新上传。当我制作模板Authors_Template.txt然后下载并重新上传它时,它可以工作。我怎么解决这个问题?我什至尝试将ALLOWED_EXTENSIONS列表缩小到just TSV,但我仍然遇到同样的问题。

应用程序.py

from werkzeug.utils import secure_filename
import flask, string, random
import json
import subprocess
import os
import re
import time


UPLOAD_FOLDER = '.'
ALLOWED_EXTENSIONS = set(['txt','tsv'])

app = flask.Flask(__name__)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = ''.join(random.choice(string.ascii_letters) for _ in range(20)) #needed to use flask.session



def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

def places_exist(filename):
    infile = open(filename, 'rU')

    placeDict = {}
    addresses_temp = []
    addresses = []
    places_temp =[]
    places = []
    places_exist = True

    for i in infile:
        item = i.rstrip("\n").split("\t")
        places_temp.append(item[0])
        addresses_temp.append(item[1])

    p_index = (places_temp.index('Place')) + 1
    a_index = (addresses_temp.index('Address')) + 1

    places = places_temp[p_index:]
    addresses = addresses_temp[a_index:]

    infile.close()

    infile = open(filename, 'rU')

    return places_exist

@app.route('/', methods=['GET'])
def home():
   return flask.render_template('index.html')

@app.route('/process_file', methods=['POST'])
def process_file():
  #here, you can run all the checks as before, but instead of flash, you can return jsonified results to read in the front-end
    if 'file' not in flask.request.files or not flask.request.files['file'].filename:
        return flask.jsonify({'result':'False', 'message':'no files selected'})
        return flask.redirect(url_for('home'))
    file = flask.request.files['file']
    filename = secure_filename(file.filename)
    if not allowed_file(file.filename):
        return flask.jsonify({'result':'False', 'message':'Must be TXT file!'})
        return flask.redirect(url_for('home'))
    if not places_exist(os.path.join(app.config['UPLOAD_FOLDER'], filename)):
        return flask.jsonify({'result':'False', 'message':'There is an affiliation missing from your Place list. Please re-try.'})
        return flask.redirect(url_for('home'))
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    flask.session['filename'] = filename
    return flask.jsonify({'result':'True'})

更新:

def process_file():
  #here, you can run all the checks as before, but instead of flash, you can return jsonified results to read in the front-end
    if 'file' not in flask.request.files or not flask.request.files['file'].filename:
        return flask.jsonify({'result':'False', 'message':'no files selected'})
        return flask.redirect(url_for('home'))
    file = flask.request.files['file']
    filename = secure_filename(file.filename)
    if not allowed_file(file.filename):
        return flask.jsonify({'result':'False', 'message':'Must be TXT file!'})
        return flask.redirect(url_for('home'))
    # Save the file in the temp folder
    file.save(os.path.join(app.config['TEMP_FOLDER'], filename))
    # Process the file 
    if not places_exist(os.path.join(app.config['TEMP_FOLDER'], filename)):
        return flask.jsonify({'result':'False', 'message':'There is an affiliation missing from your Place list. Please re-try.'})
        return flask.redirect(url_for('home'))
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    flask.session['filename'] = filename
    return flask.jsonify({'result':'True'})

标签: htmlflaskflask-wtforms

解决方案


您正在尝试在将文件写入目录之前读取文件。首先,您需要将文件保存在应用程序上传目录中,然后读取它。

def process_file():
    # here, you can run all the checks as before, but instead of flash, you can return jsonified results to read in the front-end
    if 'file' not in flask.request.files or not flask.request.files['file'].filename:
        return flask.jsonify({'result':'False', 'message':'no files selected'})
        return flask.redirect(url_for('home'))
    file = flask.request.files['file']
    filename = secure_filename(file.filename)
    if not allowed_file(file.filename):
        return flask.jsonify({'result':'False', 'message':'Must be TXT file!'})
        return flask.redirect(url_for('home'))
    # Save the file in the correct Location
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    # Process your file already saved
    if not places_exist(os.path.join(app.config['UPLOAD_FOLDER'], filename)):
        return flask.jsonify({'result':'False', 'message':'There is an affiliation missing from your Place list. Please re-try.'})
        return flask.redirect(url_for('home'))

    flask.session['filename'] = filename
    return flask.jsonify({'result':'True'})

编辑:如果您需要在保存之前检查文件,则必须小心,如果您立即保存,您将覆盖旧文件,一个好的方法是将文件保存在临时位置,检查该文件然后保存最终目录,显然删除了 tmp 文件夹中的文件。

PS:您还有 2 个返回,如果您需要以 HTML 或 JSON 格式响应,则必须检查请求的标头。


推荐阅读