我创建了一个flask网站,使表单及其相应结果显示在同一页面上。我遇到的问题是,当我第一次执行flask run
并加载网站时,第一次单击“提交”按钮时,出现以下关键错误:
File "/Users/cdastmalchi/Desktop/author_script/app.py", line 106, in upload_vals
proc = subprocess.Popen('python author_script.py {} -p {} -s {} -m {}'.format(flask.session['filename'], 'y' if payload['period'] == 'yes' else 'n', 'y' if payload['space'] == 'yes' else 'n', payload['affiliation'][:3]), shell=True, stdout=subprocess.PIPE)
File "/Users/cdastmalchi/miniconda2/lib/python2.7/site-packages/werkzeug/local.py", line 378, in <lambda>
__getitem__ = lambda x, i: x._get_current_object()[i]
File "/Users/cdastmalchi/miniconda2/lib/python2.7/site-packages/flask/sessions.py", line 83, in __getitem__
return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'filename'
但是,如果我第二次单击提交按钮,则结果将正常显示。甚至更奇怪的是,如果我不杀掉flask应用程序,而只是在网页上进行一次硬刷新,然后再次提交表单,这一次,结果只显示一次单击,而不是两次。
如何获取它,以便如果我刚刚启动了flask应用程序,只需单击一次提交即可显示结果?
源代码
app.py:
TEMPLATE_FILE = 'ExampleAuthorList.txt'
UPLOAD_FOLDER = '.'
ALLOWED_EXTENSIONS = set(['txt'])
app = flask.Flask(__name__)
app.config['TEMPLATE_FILE'] = TEMPLATE_FILE
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = ''.join(random.choice(string.ascii_letters) for _ in range(20)) #needed to use flask.session
@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'})
@app.route('/upload_vals')
def upload_vals():
payload = json.loads(flask.request.args.get('payload'))
proc = subprocess.Popen('python author_script.py {} -p {} -s {} -m {}'.format(flask.session['filename'], 'y' if payload['period'] == 'yes' else 'n', 'y' if payload['space'] == 'yes' else 'n', payload['affiliation'][:3]), shell=True, stdout=subprocess.PIPE)
while proc.poll() is None:
time.sleep(0.5)
with open("templates/authorList.html") as f:
data = ''.join(f.readlines())
return flask.jsonify({'data':data})
index.html:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<link rel="shortcut icon" href="static/favicon.ico">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div class="container" id="TheForm">
<div class="row">
<div class="col-sm-6">
<h1><img src="static/Lab_Logo_v6c.png" style="width: 120px; float: left;margin-right: 20px;margin-left: -16px;margin-top: -40px;border: 10px">Author List Script</h1>
<br><br><br>
<p>Download the template file below and re-upload with your custom author information:</p>
<br>
<a href="static/ExampleAuthorList.txt" download="Authors_Template.txt"><button type="button">Download</button></a><br><br>
<form action="" id="myform" method=post enctype=multipart/form-data>
<input type=file name=file value="Choose File">
<p class='error_message'></p>
</form>
<div id="buttonDiv">
<p>Mark affiliations with:</p>
<input type="radio" name="affiliation" value="number" data-key='affiliation' data-value='number' class="form-radio main_checkbox" checked><label for="number">Number</label><br>
<input type="radio" name="affiliation" value="letter" data-key='affiliation' data-value='letter' class="form-radio main_checkbox"><label for="letter">Letter</label><br>
<p>Separate initials with period:</p>
<input type="radio" name="period" value="separated" data-key='period' data-value='yes' class="form-radio period"><label for="period">Yes</label><br>
<input type="radio" name="period" data-key='period' data-value='no' value="separated" class="form-radio period" checked><label for="period">No</label>
<br>
<p>Separate initials with space:</p>
<input type="radio" name="space" value="separated" data-key='space' data-value='yes' class="form-radio spacing"><label for="space">Yes</label><br>
<input type="radio" name="space" data-key='space' data-value='no' value="separated" class="form-radio spacing" checked><label for="space">No</label><br>
</div>
<button class='submit_data'>Submit</button>
</div>
<div class="col-sm-6">
<div>
<h1>Results</h1>
<p class="my-results"></p>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#TheForm').on('click', '.submit_data', function(){
var form_data = new FormData($('#myform')[0]);
var flag = true;
$.ajax({
type: 'POST',
url: '/process_file',
data: form_data,
contentType: false,
cache: false,
processData: false,
success: function(data) {
if (data.result === 'False'){
$('.error_message').html(data.message)
flag = false;
}
},
});
var payload = {};
$('.form-radio').each(function(){
if ($(this).prop('checked')){
payload[$(this).data('key')] = $(this).data('value');
}
});
$.ajax({
url: "/upload_vals",
type: "get",
data: {'payload':JSON.stringify(payload)},
success: function(response) {
$(".my-results").html(response.data);
},
});
});
});
</script>
</body>
</html>