使用 flask 和 WTForms 在一个页面中使用多个表单,其中一个表单 link 到另一个
Multiple forms in a single page using flask and WTForms in which one form link to another
这是现在的样子:
这就是我需要的
- 我需要两个表单,一个在同一页面中链接到另一个。
- 第一个表格:会有一个输入框供用户填写。
- 如果条目有效,系统应引导用户进入第二个表单。
- 表单会打印出系统查找的结果,并要求用户在输入框中输入一个数字。
- 系统将查看输入是否有效。如果是,它将执行一系列操作()
(粗体字为有效部分)
我的代码:
主要功能
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
if form1.submit1.data and form1.validate():
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
if form2.submit2.data and form2.validate(): #######
user_select = int(form2.area.data)
if(user_select>0 or user_select<=len(allMatch)):
user= allMatch[user_select-1]
author_name = user.username
posts = Post.query.filter_by(author=author_name).all()
emty_list = []
while(len(posts)!= emty_list):
db.session.delete(posts[0])
db.session.delete(user)
db.session.commit()
return redirect(url_for('home'))
flash('change have been made successfully', 'success')
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
else:
return redirect(url_for('searchArea'))
flash('check your entry', 'danger')#######
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
return render_template('searchArea.html', title='Account',form=form1)
forms.py
class FindArea(FlaskForm):
area1=TextAreaField('Area Code', validators=[DataRequired()])
submit1 = SubmitField('Search')
class SelectUser(FlaskForm):
area2=TextAreaField('user number', validators=[DataRequired()])
submit2 = SubmitField('confirm')
模板(searchArea.html)
{% extends "layout.html"%} {% block content %}
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.area1.label(class="form-control-label") }} {% if form.area1.errors %} {{ form.area1(class="form-control form-control-lg
is-invalid") }}
<div class="invalid-feedback">
{% for error in form.area1.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.area1(class="form-control form-control-lg") }}
{% endif %}
</div>
{{ form.submit1(class="btn btn-outline-info") }}
</form>
</div>
{% endblock content %}
模板(print_area.html)
{% extends "layout.html"%} {% block content %}
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.area.label(class="form-control-label") }} {% if form.area.errors %} {{ form.area(class="form-control form-control-lg
is-invalid") }}
<div class="invalid-feedback">
{% for error in form.area.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.area(class="form-control form-control-lg") }}
{% endif %}
</div>
{{ form.submit(class="btn btn-outline-info") }}
</form>
</div>
{% endblock content %}
任何帮助都会很棒!
谢谢!
当你点击form2的提交按钮时,这个条件(if form1.submit1.data and form1.validate():
)是False.Maybe你需要改变代码逻辑。
好的,这就是我从这节课中学到的东西。 form.validate()
和 return render
是一件非常棘手的事情,从上到下编码 运行 两次,第一次当你进入页面时它不验证但渲染,第二次它验证;除了添加一个变量来检查是否已提交第一个表单,你真的不能对它做任何事情,并且 return 在第一个表单尚未提交时首先呈现,否则 return 呈现第二个。这是我对代码的修复:
主要功能
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
global allMatch
form1Passer = False
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
if form1.submit1.data and form1.validate() and form1Passer == False: # notice the order
form1Passer == True
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
if form2.submit2.data and form2.validate(): # notice the order
user_select = int(form2.area2.data)
if(user_select>0 and user_select<=len(allMatch)):
print("0")
user= allMatch[user_select-1]
print("1")
print("2")
posts = Post.query.filter_by(author=user).all()
print(type(posts))
while(True):
try:
db.session.delete(posts[0])
except:
break
db.session.delete(user)
db.session.commit()
return redirect(url_for('home'))
flash('change have been made successfully', 'success')
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
else:
return redirect(url_for('searchArea'))
flash('check your entry', 'danger')
if form1Passer == False:
return render_template('searchArea.html', title='Account',form=form1)
else:
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
无需修改。如果你和我有同样的问题希望这对你有帮助!
编辑:上面的代码完全有效(但这是一种糟糕的做法)但是当查询 returns 列表时,其中的对象没有链接到对象本身!
有点像超市的地址!
当您更改您发布的地址时,不会影响超市的实际位置。
而且超市搬家时地址不会自动更新!
使用 filter 方法和 .first() 可以避免任何可能的未来问题!由于 .first() 是对象本身的直接控制器
当您只为对象赋值时(例如:post_target.prperty = value),下面的代码也可以工作,而上面的代码不会(# 是我修改的行):
allMatch=[] #
user; #
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
global allMatch
global user
form1Passer = False
form2Passer = False
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
form3 = ConfirmForm()
if form1.submit1.data and form1.validate() and form1Passer == False: # notice the order
form1Passer == True
if(form1.area1.data == "0"):
flash('this is an illegal move', 'danger')
return redirect(url_for('searchArea'))
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
if form2.submit2.data and form2.validate() and form2Passer == False: # notice the order
user_select = int(form2.area2.data)
if(user_select>0 and user_select<=len(allMatch)):
user= allMatch[user_select-1]
return render_template('confirm.html', title='Account',user=user,form=form3)
else:
flash('check your entry', 'danger')
return redirect(url_for('searchArea'))
if form3.submit_cancel.data and form3.validate():
return redirect(url_for('searchArea'))
if form3.submit_confirm.data and form3.validate():
user_target = User.query.filter_by(email = user.email).first()#
while(True):
try:
post_target = Post.query.filter_by(author=user_target).first()#
db.session.delete(post_target)#
db.session.commit()
except:
break
db.session.delete(user_target)#
db.session.commit()
flash('change have been made successfully', 'success')
return redirect(url_for('home'))
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
if form1Passer == False:
return render_template('searchArea.html', title='Account',form=form1)
elif form2Passer == False:
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
else:
return render_template('confirm.html', title='Account',user=user,form=form3)
elif current_user.is_authenticated:
abort(403)
else:
return redirect(url_for('home'))
这是现在的样子:
这就是我需要的
- 我需要两个表单,一个在同一页面中链接到另一个。
- 第一个表格:会有一个输入框供用户填写。
- 如果条目有效,系统应引导用户进入第二个表单。
- 表单会打印出系统查找的结果,并要求用户在输入框中输入一个数字。
- 系统将查看输入是否有效。如果是,它将执行一系列操作()
(粗体字为有效部分)
我的代码:
主要功能
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
if form1.submit1.data and form1.validate():
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
if form2.submit2.data and form2.validate(): #######
user_select = int(form2.area.data)
if(user_select>0 or user_select<=len(allMatch)):
user= allMatch[user_select-1]
author_name = user.username
posts = Post.query.filter_by(author=author_name).all()
emty_list = []
while(len(posts)!= emty_list):
db.session.delete(posts[0])
db.session.delete(user)
db.session.commit()
return redirect(url_for('home'))
flash('change have been made successfully', 'success')
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
else:
return redirect(url_for('searchArea'))
flash('check your entry', 'danger')#######
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
return render_template('searchArea.html', title='Account',form=form1)
forms.py
class FindArea(FlaskForm):
area1=TextAreaField('Area Code', validators=[DataRequired()])
submit1 = SubmitField('Search')
class SelectUser(FlaskForm):
area2=TextAreaField('user number', validators=[DataRequired()])
submit2 = SubmitField('confirm')
模板(searchArea.html)
{% extends "layout.html"%} {% block content %}
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.area1.label(class="form-control-label") }} {% if form.area1.errors %} {{ form.area1(class="form-control form-control-lg
is-invalid") }}
<div class="invalid-feedback">
{% for error in form.area1.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.area1(class="form-control form-control-lg") }}
{% endif %}
</div>
{{ form.submit1(class="btn btn-outline-info") }}
</form>
</div>
{% endblock content %}
模板(print_area.html)
{% extends "layout.html"%} {% block content %}
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.area.label(class="form-control-label") }} {% if form.area.errors %} {{ form.area(class="form-control form-control-lg
is-invalid") }}
<div class="invalid-feedback">
{% for error in form.area.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.area(class="form-control form-control-lg") }}
{% endif %}
</div>
{{ form.submit(class="btn btn-outline-info") }}
</form>
</div>
{% endblock content %}
任何帮助都会很棒! 谢谢!
当你点击form2的提交按钮时,这个条件(if form1.submit1.data and form1.validate():
)是False.Maybe你需要改变代码逻辑。
好的,这就是我从这节课中学到的东西。 form.validate()
和 return render
是一件非常棘手的事情,从上到下编码 运行 两次,第一次当你进入页面时它不验证但渲染,第二次它验证;除了添加一个变量来检查是否已提交第一个表单,你真的不能对它做任何事情,并且 return 在第一个表单尚未提交时首先呈现,否则 return 呈现第二个。这是我对代码的修复:
主要功能
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
global allMatch
form1Passer = False
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
if form1.submit1.data and form1.validate() and form1Passer == False: # notice the order
form1Passer == True
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
if form2.submit2.data and form2.validate(): # notice the order
user_select = int(form2.area2.data)
if(user_select>0 and user_select<=len(allMatch)):
print("0")
user= allMatch[user_select-1]
print("1")
print("2")
posts = Post.query.filter_by(author=user).all()
print(type(posts))
while(True):
try:
db.session.delete(posts[0])
except:
break
db.session.delete(user)
db.session.commit()
return redirect(url_for('home'))
flash('change have been made successfully', 'success')
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
else:
return redirect(url_for('searchArea'))
flash('check your entry', 'danger')
if form1Passer == False:
return render_template('searchArea.html', title='Account',form=form1)
else:
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
无需修改。如果你和我有同样的问题希望这对你有帮助!
编辑:上面的代码完全有效(但这是一种糟糕的做法)但是当查询 returns 列表时,其中的对象没有链接到对象本身!
有点像超市的地址! 当您更改您发布的地址时,不会影响超市的实际位置。
而且超市搬家时地址不会自动更新!
使用 filter 方法和 .first() 可以避免任何可能的未来问题!由于 .first() 是对象本身的直接控制器
当您只为对象赋值时(例如:post_target.prperty = value),下面的代码也可以工作,而上面的代码不会(# 是我修改的行):
allMatch=[] #
user; #
@app.route("/searchArea", methods=['GET', 'POST'])
@login_required
def searchArea():
global allMatch
global user
form1Passer = False
form2Passer = False
if current_user.is_authenticated and verifyIdentity(current_user.username)==True:
form1 = FindArea()
form2 = SelectUser()
form3 = ConfirmForm()
if form1.submit1.data and form1.validate() and form1Passer == False: # notice the order
form1Passer == True
if(form1.area1.data == "0"):
flash('this is an illegal move', 'danger')
return redirect(url_for('searchArea'))
allMatch = User.query.filter_by(area=form1.area1.data).all()
if(allMatch == []):
flash('area code does not exist', 'danger')
return redirect(url_for('searchArea'))
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
if form2.submit2.data and form2.validate() and form2Passer == False: # notice the order
user_select = int(form2.area2.data)
if(user_select>0 and user_select<=len(allMatch)):
user= allMatch[user_select-1]
return render_template('confirm.html', title='Account',user=user,form=form3)
else:
flash('check your entry', 'danger')
return redirect(url_for('searchArea'))
if form3.submit_cancel.data and form3.validate():
return redirect(url_for('searchArea'))
if form3.submit_confirm.data and form3.validate():
user_target = User.query.filter_by(email = user.email).first()#
while(True):
try:
post_target = Post.query.filter_by(author=user_target).first()#
db.session.delete(post_target)#
db.session.commit()
except:
break
db.session.delete(user_target)#
db.session.commit()
flash('change have been made successfully', 'success')
return redirect(url_for('home'))
#return redirect(url_for('deleteUser',user=allMatch[user_select]))
if form1Passer == False:
return render_template('searchArea.html', title='Account',form=form1)
elif form2Passer == False:
return render_template('print_area.html', title='Account',users=allMatch,form=form2)
else:
return render_template('confirm.html', title='Account',user=user,form=form3)
elif current_user.is_authenticated:
abort(403)
else:
return redirect(url_for('home'))