最初,我在一个网页上有一个很长的Flask表单,但是现在我想将该表单分解为较小的块,并使用分页按钮遍历这些块。我只是对如何处理这个问题感到困惑。
到目前为止,我已经为这些不同的“块”创建了单独的表单类和html模板,但是我不确定如何在主app.py脚本中将它们捆绑在一起。我本来打算采用动态路由方法,但我认为我做的不正确。有什么建议吗?
表单类:
from flask_wtf import FlaskForm
from wtforms import StringField, TextField, SubmitField, IntegerField, SelectField, validators
class InputForm1(FlaskForm):
stack_name = StringField('STACK NAME', validators=[validators.required()])
resource_cfn_tmpl_deploy_bucket = SelectField('PIPELINE DEPLOYMENT BUCKET', validators=[validators.required()])
key_pair = SelectField('KEY PAIR', validators=[validators.required()])
start_point = SelectField('START POINT', validators=[validators.required()], choices=[("", "---"), ("", "fastq"), ("", "bam"), ("", "hdof"), ("", "gvcf"), ("", "vcf")])
qc = SelectField('QC', choices=[("", "---"), ("","BAM"), ("","VCF")])
class InputForm2(FlaskForm):
input_uri = StringField('INPUT BUCKET', validators=[validators.required()])
output_uri = StringField('OUTPUT BUCKET', validators=[validators.required()])
ref_uri = SelectField('REFERENCE BUCKET', validators=[validators.required()])
user_assets_uri = StringField('USER ASSETS BUCKET', validators=[validators.required()])
class InputForm3(FlaskForm):
target = StringField('TARGET')
package_name = StringField('PACKAGE NAME', validators=[validators.required()])
license_name = StringField('LICENSE NAME', validators=[validators.required()])
class InputForm4(FlaskForm):
cohort_prefix = StringField('COHORT PREFIX', validators=[validators.required()])
build = SelectField('BUILD', validators=[validators.required()], choices=[("", "---"), ("","GRCh38"), ("","GRCh37")])
ome = SelectField('OME', validators=[validators.required()], choices=[("", "---"), ("", "wgs"), ("", "wes")])
class InputForm5(FlaskForm):
cloudspan_mode = SelectField('CLOUDSPAN MODE', choices=[("", "---"), ("", "validation"), ("", "qc")])
project_id = StringField('PROJECT ID')
zone = StringField('ZONE')
cloud_file = StringField('CLOUD FILE')
submit_final = SubmitField('Execute Pipeline')
pipeline_1.html:(我也有pipeline_2 ..... pipeline_5.html,具有上述Form类中定义的不同输入)
{% extends 'layout.html' %}
{% block body %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<br><br><br>
<legend class="border-bottom mb-4">Pipeline Input</legend>
<div class="form-group required">
{{ form.stack_name.label(class="form-control-label")}}
{{ form.stack_name(class="form-control form-control-lg") }}
</div>
<div class="form-group required">
{{form.resource_cfn_tmpl_deploy_bucket.label(class="form-control-label") }}
form.resource_cfn_tmpl_deploy_bucket(class="form-control form-control-lg") }}
</div>
<div class="form-group required">
{{ form.key_pair.label(class="form-control-label") }}
{{ form.key_pair(class="form-control form-control-lg") }}
</div>
<div class="form-group required">
{{ form.start_point.label(class="form-control-label") }}
{{ form.start_point(class="form-control form-control-lg") }}
</div>
<div class="form-group">
{{ form.qc.label(class="form-control-label") }}
{{ form.qc(class="form-control form-control-lg") }}
</div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link" href=href="#" tabindex="-1">Previous</a></li>
<li class="page-item"><a class="page-link" href="{{ url_for('/1') }}">1</a></li>
<li class="page-item"><a class="page-link" href="{{ url_for('/2') }}">2</a></li>
<li class="page-item"><a class="page-link" href="{{ url_for('/3') }}">3</a></li>
<li class="page-item"><a class="page-link" href="{{ url_for('/4') }}">4</a></li>
<li class="page-item"><a class="page-link" href="{{ url_for('/5') }}">5</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
</fieldset>
</div class="form-group">
</div>
</form>
<p>{{ error }}</p>
</div>
{% endblock %}
app.py:(当前尝试,我知道这是不正确的,但这是我遇到的问题)
# Import the Flask app
from flask import Flask, url_for, render_template, request, flash, redirect
from math import ceil
from datetime import datetime
from user_input import InputForm1, InputForm2, InputForm3, InputForm4, InputForm5
import json
import subprocess
import os
import sys
import boto3
app = Flask('pipeline-ui')
app.config['S3_CLIENT'] = boto3.client('s3')
app.config['EC2_CLIENT'] = boto3.client('ec2')
app.debug = True
@app.route('/<page_num>', methods=['GET', 'POST'])
def pipeline(page_num):
if request.method == "POST":
if page_num == 1:
form = InputForm1(request.form)
return redirect('/2')
if page_num == 2:
form = InputForm2(request.form)
return redirect('/3')
if page_num == 3:
form = InputForm3(request.form)
return redirect('/4')
if page_num == 4:
form = InputForm4(request.form)
return redirect('/5')
if page_num == 5:
form = InputForm5(request.form)
return redirect('results')
return render_template('pipeline_{}.html'.format(page_num), title='Pipeline Input', form=form)
答案 0 :(得分:0)
请记住,请求之间没有状态,因此,其他所有内容都正确,您需要一种方法来存储下一步骤的每一步的数据。
如果无法将每个步骤的数据存储在数据库中,则可以考虑重新排序表单,以便每个步骤都可以作为对数据库的提交。
如果您不使用数据库(或文件),或者在完成所有步骤之前无法发送数据,那么另一种选择是将每个步骤的数据存储到下一个隐藏输入中
class StepForm(FlaskForm):
previous_field = SomeField(widget=HiddenInput())
# ...
step = StepForm()
step.previous_field.data = previous_step.field.data
当然,您也可以使用javascript在前端进行分页,并在最后一次请求中完全发送所有数据。