python - 如何在 html 中显示 Flask 表单数据的摘要?
问题描述
我创建了一个多步骤表单,在最后的“页面”上,我希望它是一个“审查顺序”之类的东西,我总结了前几页的所有用户输入。不过,我实际上无法在最后一页上显示输入(使用我当前的方法)。这是我到目前为止所拥有的,我正在努力解决的部分是在下面的 html 部分Pipeline Input Review
:
应用程序.py:
@app.route('/', methods=['GET', 'POST'])
def pipeline():
form = InputForm(request.form)
if request.method == 'POST':
STACK_NAME = form.stack_name.data
BUCKET = form.bucket.data
KEY_PAIR = form.key_pair.data
return render_template('pipeline-alt.html',
title='Pipeline Input',
form=form)
管道-alt.html:
<form method="POST" id="regForm" action="">
<h1>Pipeline Input</h1>
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<label>Stack Name</label>
<input placeholder="(e.g. my-pipeline-run)..." oninput="this.className = ''" name="stack_name"></input>
<label>Pipeline Deployment S3 Bucket</label>
<input placeholder="bucket name..." oninput="this.className = ''" name="bucket">
<label>Key Pair</label>
<select placeholder="key pair..." oninput="this.className = ''" name="key_pair">
<!-- Current attempt at accessing the input data -->
<div class="tab">
<h3>Pipeline Input Review:</h3>
<label>Stack Name: {{ form.stack_name.data }}</label>
<label>Pipeline Deployment S3 Bucket: {{ form.bucket.data }}</label>
<label>Key Pair: {{ form.key_pair.data }}</label>
</div>
</form>
输入表格:
class InputForm(FlaskForm):
bucket_choices = [("", "---")] + [("", bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
ref_choices = [("", "---")] + [("", bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
key_choices = [("", "---")] + [("", pair["KeyName"]) for pair in ec2_client.describe_key_pairs()["KeyPairs"]]
stack_name = StringField('STACK NAME', validators=[validators.required()])
bucket = SelectField('PIPELINE DEPLOYMENT BUCKET', validators=[validators.required()], choices=bucket_choices)
key_pair = SelectField('KEY PAIR', validators=[validators.required()], choices=key_choices)
更新 2 尝试:
管道-alt.html
{% extends 'layout.html' %}
{% block body %}
<form method="POST" id="regForm" action="{{ url_for('pipeline') }}">
<h1>Pipeline Input</h1>
<br>
<!-- One "tab" for each step in the form: -->
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<br><br>
<label>Stack Name</label>
{{ form.stack_name(placeholder="(e.g. my-pipeline-run)...", oninput="this.className = ''")}}
<label>Pipeline Deployment S3 Bucket</label>
{{ form.bucket(placeholder="Deployment bucket name...", oninput="this.className = ''") }}
<label>Key Pair</label>
{{ form.key_pair(placeholder="AWS ssh key pair...", oninput="this.className = ''") }}
<label>Start Point</label>
{{ form.start_point(placeholder="Start point..", oninput="this.className = ''") }}
</div>
<div class="tab">
<h3>Review</h3>
<label>Stack Name: <span id="stack_name_label">{{ STACK_NAME }}</span></label>
<br>
<label>Pipeline Deployment S3 Bucket: <span id="bucket_label">{{ BUCKET }}</span></label>
<br>
<label>AWS SSH Key Pair: <span id="gpce_ssh_key_pair_label">{{ GPCE_SSH_KEY_PAIR }}</span></label>
<br>
<label>Start Point: <span id="start_point_label">{{ START_POINT }}</span></label>
</div>
<br>
<div style="overflow:auto;">
<div style="float:right;">
<button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
</div>
</div>
<!-- Circles which indicates the steps of the form: -->
<div style="text-align:center;margin-top:40px;">
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
</div>
</form>
<script>
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the crurrent tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("regForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
</script>
<script>
$(function() {
$('#stack_name').on('change keyup paste', function(){
$(#'stack_name_label').text($(this).val());
});
$('#bucket').change(function(){
$(#'bucket_label').text($(this).val());
});
$('#key_pair').change(function(){
$(#'key_pair_label').text($(this).val());
});
$('#start_point').change(function(){
$(#'start_point_label').text($(this).val());
});
});
</script>
{% endblock %}
解决方案
您没有正确使用表格,我不确定您要达到什么目的,但这里是您应该如何使用表格
在您的 HTML 中
<form method="POST" id="regForm" action="{{url_for('pipeline')}}">
<h1>Pipeline Input</h1>
<div class="tab">
<h3>Pipeline Infrastructure:</h3>
<label>Stack Name</label>
{{ form.stack_name(placeholder='yourplaceholder', oninput="this.className....") }}
<label>Pipeline Deployment S3 Bucket</label>
{{ form.bucket(placeholder='bucket name')}}
<label>Key Pair</label>
{{ form.key_pair }}
<!-- Current attempt at accessing the input data -->
<div class="tab">
<h3>Pipeline Input Review:</h3>
<label>Stack Name: <span id="stack_label">{{ STACK_NAME }}</span></label>
<label>Pipeline Deployment S3 Bucket: <span id="bucket_label"> {{ BUCKET }}</span></label>
<label>Key Pair: <span id="key_pair_label">{{ KEY_PAIR }}</span></label>
</div>
</form>
在你的 app.py
@app.route('/', methods=['GET', 'POST'])
def pipeline():
form = InputForm(request.form)
STACK_NAME = ''
BUCKET = ''
KEY_PAIR = ''
if request.method == 'POST':
STACK_NAME = request.form['stack_name'] # this is how you access the value of the input
BUCKET = request.form['bucket']
KEY_PAIR = request.form['key_pair']
return render_template('pipeline-alt.html',
title='Pipeline Input',
form=form,
STACK_NAME=STACK_NAME,
BUCKET=BUCKET,
KEY_PAIR=KEY_PAIR
)
当您想在模板中使用 WTForm 时,您可以使用{{form.input_name}}
. 这将在您的表单中呈现一个 HTML<input>
标记(或<select>
取决于您的表单定义)。不要使用{{form.inpute_name.data}}
request.form['input_name']
在您看来,如果 form 方法是 typePOST
或request.args.get('input_name')
form方法是 type ,则访问使用您使用的表单提交的数据GET
更新
您应该确保您的选择元组的第一个元素不是空字符串,因为这是在您提交表单时传递给您的视图的值。
尝试将其更改如下:
class InputForm(FlaskForm):
bucket_choices = [("", "---")] + [('bucket["Name"]', bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
ref_choices = [("", "---")] + [('bucket["Name"]', bucket["Name"]) for bucket in s3_client.list_buckets()["Buckets"]]
key_choices = [("", "---")] + [('pair["KeyName"]', pair["KeyName"]) for pair in ec2_client.describe_key_pairs()["KeyPairs"]]
stack_name = StringField('STACK NAME', validators=[validators.required()])
bucket = SelectField('PIPELINE DEPLOYMENT BUCKET', validators=[validators.required()], choices=bucket_choices)
key_pair = SelectField('KEY PAIR', validators=[validators.required()], choices=key_choices)
更新#2
您没有在原始问题中指定要在提交表单之前立即反映输入的更改。这只能使用 javascript。
将以下 javascript 代码添加到您的 HTML。这些是事件侦听器,用于侦听表单输入中的任何更改。每次检测到更改时,相应的标签文本都会相应更改。还要检查上面更新的 HTML 代码。我<span>
在您的标签中添加了标签,以反映 javascript 代码的更改
$(function(){
$('#stack_name').on('change keyup paste', function(){
$(#'stack_label').text($(this).val());
});
$('#bucket').change(function(){
$(#'bucket_label').text($(this).val());
});
$('#key_pair').change(function(){
$(#'key_pair_label').text($(this).val());
});
});
推荐阅读
- flutter - TextField 标签边框位置
- c# - 将数组限制为特定类型 - 自定义纹理类 C#?
- elasticsearch - 查找与我在同一公司的人的简单方法?
- travis-ci - travis 为草稿版本部署提供者
- python-3.x - 不知道我在这里做错了什么(python3)
- haskell - 如何堵住这种类型的孔 3
- python - 机器人框架:For循环不包含关键字
- java - java - 如何使用JavaFX中的字符串从具有对象作为值的组合框中选择数据?
- c++ - 我将如何从 csv 文件中准确读取某些值?
- django-rest-framework - 用于 GET 请求的 drf-yasg 文档输入和输出序列化程序