更新表单验证同一页面上的其他表单而不是她自己(Flask)
Update form validates the other form on same page instead of herself (Flask)
我是 Flask 的新手,正在使用它创建我的第一个项目。我试图在同一页面上获取一些表格:上面用于创建会议的表格和 bootstrap 模态(更新、删除)中的其他 2 个表格,用于 table 中的每一行。创建表单和删除表单工作正常,但问题是当我使用更新表单时。我想在表单中包含 object 中的值,以便轻松更新它们。我不知道为什么,但是当我尝试更新会议并点击提交(“保存更改”)时,表单会使用更新表单中的值提交“create_form”。有趣的是,我得到了创建用户的另一个页面(相同的方法 - 3 种形式(2 种带有模态)和 .validate_on_submit 在同一路线),并且一切正常(更新形式不提交创建表格)。我认为 .validate_on_submit() 足以区分这两种形式的用法,但现在我很困惑。我应该分离代码,并为更新和删除创建新的路由,还是还有其他事情要做?
这是代码。
路线:
@creator.route('/meetings', methods=['GET', 'POST'])
@login_required
@usertype_required('coach')
def meetings_page():
meetings = Meeting.query.order_by(Meeting.date).all()
create_meeting_form = CreateMeetingForm()
update_meeting_form = UpdateMeetingForm()
delete_meeting_form = DeleteForm()
if create_meeting_form.validate_on_submit():
meeting_to_create = Meeting(date=create_meeting_form.date.data,
hour=str(create_meeting_form.hour.data)[:5],
day=weekdays_tuple[create_meeting_form.date.data.weekday()],
type=create_meeting_form.type.data,
locality=create_meeting_form.locality.data,
pitch=create_meeting_form.pitch.data)
db.session.add(meeting_to_create)
db.session.commit()
flash("Meeting created successfully!", category='info')
return redirect(url_for('creator.meetings_page'))
if update_meeting_form.validate_on_submit():
meeting_to_update = request.form.get('update_meeting')
update_meeting = Meeting.query.filter_by(meeting_id=meeting_to_update).first()
if update_meeting:
update_meeting.date = update_meeting_form.date.data
update_meeting.hour = str(update_meeting_form.hour.data)[:5]
update_meeting.pitch = update_meeting_form.pitch.data
update_meeting.locality = update_meeting_form.locality.data
update_meeting.type = update_meeting_form.type.data
db.session.commit()
flash("Changed meeting info!", category='info')
return redirect(url_for('creator.meetings_page'))
if delete_meeting_form.validate_on_submit():
meeting_to_delete = request.form.get('delete_meeting')
del_meeting = Meeting.query.filter_by(meeting_id=meeting_to_delete).first()
if del_meeting:
db.session.delete(del_meeting)
db.session.commit()
flash("Deleted meeting successfully!", category='info')
return redirect(url_for('creator.meetings_page'))
return render_template('creator/meetings.html',
create_meeting_form=create_meeting_form,
update_form=update_meeting_form,
delete_form=delete_meeting_form,
meetings=meetings)
模板:
{% block content %}
<div class="container">
<form method="POST" class="form-control">
{{ create_meeting_form.csrf_token }}
{{ create_meeting_form.date.label }}
{{ create_meeting_form.date(class="form-control") }}
<br/>
{{ create_meeting_form.hour.label }}
{{ create_meeting_form.hour(class="form-control") }}
<br/>
{{ create_meeting_form.locality.label }}
{{ create_meeting_form.locality(class="form-control") }}
<br/>
{{ create_meeting_form.type.label }}
{{ create_meeting_form.type(class="form-control") }}
<br/>
{{ create_meeting_form.pitch.label }}
{{ create_meeting_form.pitch(class="form-control") }}
<br/>
<div class="text-center">
{{ create_meeting_form.submit(class="btn btn-lg btn-block btn-primary") }}
</div>
</form>
</div>
<br/>
<br/>
<br/>
<div class="container">
<table class="table table-bordered">
<thead class="text-center">
<tr>
<th scope="col">Date</th>
<th scope="col">Day</th>
<th scope="col">Hour</th>
<th scope="col">Pitch</th>
<th scope="col">Locality</th>
<th scope="col">Type</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for meeting in meetings %}
{% include 'includes/meetings_modals.html' %}
<tr>
<td>{{ meeting.date }}</td>
<td>{{ meeting.day }}</td>
<td>{{ meeting.hour }}</td>
<td>{{ meeting.pitch.title().replace("_"," ") }}</td>
<td>{{ meeting.locality }}</td>
<td>{{ meeting.type.title() }}</td>
{% if current_user.user_type == 'player' %}
<td>
<button class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#Modal-ChangeMeeting-{{ meeting.meeting_id }}">
Change
</button>
<button class="btn btn-danger"
data-bs-toggle="modal"
data-bs-target="#Modal-DeleteMeeting-{{ meeting.meeting_id }}">
Delete
</button>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
模态:
<!-- Modal Change Meeting -->
<div class="modal fade" id="Modal-ChangeMeeting-{{ meeting.meeting_id }}" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="ChangeMeetingModalLabel">
Change:
{{ meeting.type.title() }} ({{ meeting.date }} - {{ meeting.hour }})
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="POST">
<div class="modal-body">
{{ update_form.csrf_token }}
{{ update_form.date.label }}
{{ update_form.date(class="form-control", value=meeting.date) }}
<br/>
{{ update_form.hour.label }}
{{ update_form.hour(class="form-control", value=meeting.hour) }}
<br/>
{{ update_form.locality.label }}
{{ update_form.locality(class="form-control", value=meeting.locality) }}
<br/>
{{ update_form.type.label }}
{{ update_form.type(class="form-control", value=meeting.type) }}
<br/>
{{ update_form.pitch.label }}
{{ update_form.pitch(class="form-control", value=meeting.pitch) }}
<br/>
</div>
<div class="modal-footer">
<input id="update_meeting" name="update_meeting" type="hidden" value="{{ meeting.meeting_id }}">
{{ update_form.submit(class="btn btn-success", value="Save Changes") }}
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Meeting -->
<div class="modal fade" id="Modal-DeleteMeeting-{{ meeting.meeting_id }}" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="DeleteMeetingModalLabel">Delete Meeting</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete meeting - {{ meeting.date }} ({{ meeting.hour }})?</p>
</div>
<div class="modal-footer">
<div class="text-center">
<form method="POST">
{{ delete_form.csrf_token }}
<input id="delete_meeting" name="delete_meeting" type="hidden" value="{{ meeting.meeting_id }}">
{{ delete_form.submit(class="btn btn-danger") }}
</form>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
表格:
type_choices = [('training', 'Training'),('match', 'Match')]
pitch_choices = [('training_ground', 'Training Ground'), ('stadium', 'Stadium')]
class CreateMeetingForm(FlaskForm):
date = DateField('Date', validators=[DataRequired()])
hour = TimeField('Hour', validators=[DataRequired()])
type = SelectField('Type', choices=type_choices, validators=[DataRequired()])
locality = StringField('Locality', validators=[Length(min=2, max=20), DataRequired()])
pitch = SelectField('Pitch', choices=pitch_choices, validators=[DataRequired()])
submit = SubmitField('Create meeting!')
class UpdateMeetingForm(FlaskForm):
date = DateField('Date')
hour = TimeField('Hour')
type = SelectField('Type', choices=type_choices)
locality = StringField('Locality', validators=[Length(min=2, max=20)])
pitch = SelectField('Pitch', choices=pitch_choices)
submit = SubmitField('Update meeting!')
这是一个解决方案:
from flask import Flask, url_for, render_template_string
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'some_rndm_key'
class NameForm(FlaskForm):
name = StringField('Name')
submit = SubmitField('Submit Form')
class PhoneForm(FlaskForm):
phone = StringField('Phone')
submit = SubmitField('Submit Form')
@app.route('/')
@app.route('/<form>', methods=['GET', 'POST'])
def home(form=None):
name_form = NameForm()
phone_form = PhoneForm()
if form == 'name_form' and name_form.validate_on_submit():
return 'Submitted name form'
elif form == 'phone_form' and phone_form.validate_on_submit():
return 'Submitted phone form'
return render_template_string('<form method="POST" action="{{ url_for("home", form="name_form") }}">'
'{{ name_form.hidden_tag() }}'
'{{ name_form.name.label }}'
'{{ name_form.name }}'
'{{ name_form.submit }}'
'</form>'
'<br>'
'<form method="POST" action="{{ url_for("home", form="phone_form") }}">'
'{{ phone_form.hidden_tag() }}'
'{{ phone_form.phone.label }}'
'{{ phone_form.phone }}'
'{{ phone_form.submit }}'
'</form>', phone_form=phone_form, name_form=name_form)
app.run(debug=True)
基本上有一个带有变量的路由,在 <form>
标记中,您将操作指定为相同的路由,但添加到变量然后检查变量是什么,非常简单
我是 Flask 的新手,正在使用它创建我的第一个项目。我试图在同一页面上获取一些表格:上面用于创建会议的表格和 bootstrap 模态(更新、删除)中的其他 2 个表格,用于 table 中的每一行。创建表单和删除表单工作正常,但问题是当我使用更新表单时。我想在表单中包含 object 中的值,以便轻松更新它们。我不知道为什么,但是当我尝试更新会议并点击提交(“保存更改”)时,表单会使用更新表单中的值提交“create_form”。有趣的是,我得到了创建用户的另一个页面(相同的方法 - 3 种形式(2 种带有模态)和 .validate_on_submit 在同一路线),并且一切正常(更新形式不提交创建表格)。我认为 .validate_on_submit() 足以区分这两种形式的用法,但现在我很困惑。我应该分离代码,并为更新和删除创建新的路由,还是还有其他事情要做?
这是代码。
路线:
@creator.route('/meetings', methods=['GET', 'POST'])
@login_required
@usertype_required('coach')
def meetings_page():
meetings = Meeting.query.order_by(Meeting.date).all()
create_meeting_form = CreateMeetingForm()
update_meeting_form = UpdateMeetingForm()
delete_meeting_form = DeleteForm()
if create_meeting_form.validate_on_submit():
meeting_to_create = Meeting(date=create_meeting_form.date.data,
hour=str(create_meeting_form.hour.data)[:5],
day=weekdays_tuple[create_meeting_form.date.data.weekday()],
type=create_meeting_form.type.data,
locality=create_meeting_form.locality.data,
pitch=create_meeting_form.pitch.data)
db.session.add(meeting_to_create)
db.session.commit()
flash("Meeting created successfully!", category='info')
return redirect(url_for('creator.meetings_page'))
if update_meeting_form.validate_on_submit():
meeting_to_update = request.form.get('update_meeting')
update_meeting = Meeting.query.filter_by(meeting_id=meeting_to_update).first()
if update_meeting:
update_meeting.date = update_meeting_form.date.data
update_meeting.hour = str(update_meeting_form.hour.data)[:5]
update_meeting.pitch = update_meeting_form.pitch.data
update_meeting.locality = update_meeting_form.locality.data
update_meeting.type = update_meeting_form.type.data
db.session.commit()
flash("Changed meeting info!", category='info')
return redirect(url_for('creator.meetings_page'))
if delete_meeting_form.validate_on_submit():
meeting_to_delete = request.form.get('delete_meeting')
del_meeting = Meeting.query.filter_by(meeting_id=meeting_to_delete).first()
if del_meeting:
db.session.delete(del_meeting)
db.session.commit()
flash("Deleted meeting successfully!", category='info')
return redirect(url_for('creator.meetings_page'))
return render_template('creator/meetings.html',
create_meeting_form=create_meeting_form,
update_form=update_meeting_form,
delete_form=delete_meeting_form,
meetings=meetings)
模板:
{% block content %}
<div class="container">
<form method="POST" class="form-control">
{{ create_meeting_form.csrf_token }}
{{ create_meeting_form.date.label }}
{{ create_meeting_form.date(class="form-control") }}
<br/>
{{ create_meeting_form.hour.label }}
{{ create_meeting_form.hour(class="form-control") }}
<br/>
{{ create_meeting_form.locality.label }}
{{ create_meeting_form.locality(class="form-control") }}
<br/>
{{ create_meeting_form.type.label }}
{{ create_meeting_form.type(class="form-control") }}
<br/>
{{ create_meeting_form.pitch.label }}
{{ create_meeting_form.pitch(class="form-control") }}
<br/>
<div class="text-center">
{{ create_meeting_form.submit(class="btn btn-lg btn-block btn-primary") }}
</div>
</form>
</div>
<br/>
<br/>
<br/>
<div class="container">
<table class="table table-bordered">
<thead class="text-center">
<tr>
<th scope="col">Date</th>
<th scope="col">Day</th>
<th scope="col">Hour</th>
<th scope="col">Pitch</th>
<th scope="col">Locality</th>
<th scope="col">Type</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for meeting in meetings %}
{% include 'includes/meetings_modals.html' %}
<tr>
<td>{{ meeting.date }}</td>
<td>{{ meeting.day }}</td>
<td>{{ meeting.hour }}</td>
<td>{{ meeting.pitch.title().replace("_"," ") }}</td>
<td>{{ meeting.locality }}</td>
<td>{{ meeting.type.title() }}</td>
{% if current_user.user_type == 'player' %}
<td>
<button class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#Modal-ChangeMeeting-{{ meeting.meeting_id }}">
Change
</button>
<button class="btn btn-danger"
data-bs-toggle="modal"
data-bs-target="#Modal-DeleteMeeting-{{ meeting.meeting_id }}">
Delete
</button>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
模态:
<!-- Modal Change Meeting -->
<div class="modal fade" id="Modal-ChangeMeeting-{{ meeting.meeting_id }}" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="ChangeMeetingModalLabel">
Change:
{{ meeting.type.title() }} ({{ meeting.date }} - {{ meeting.hour }})
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="POST">
<div class="modal-body">
{{ update_form.csrf_token }}
{{ update_form.date.label }}
{{ update_form.date(class="form-control", value=meeting.date) }}
<br/>
{{ update_form.hour.label }}
{{ update_form.hour(class="form-control", value=meeting.hour) }}
<br/>
{{ update_form.locality.label }}
{{ update_form.locality(class="form-control", value=meeting.locality) }}
<br/>
{{ update_form.type.label }}
{{ update_form.type(class="form-control", value=meeting.type) }}
<br/>
{{ update_form.pitch.label }}
{{ update_form.pitch(class="form-control", value=meeting.pitch) }}
<br/>
</div>
<div class="modal-footer">
<input id="update_meeting" name="update_meeting" type="hidden" value="{{ meeting.meeting_id }}">
{{ update_form.submit(class="btn btn-success", value="Save Changes") }}
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Meeting -->
<div class="modal fade" id="Modal-DeleteMeeting-{{ meeting.meeting_id }}" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="DeleteMeetingModalLabel">Delete Meeting</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete meeting - {{ meeting.date }} ({{ meeting.hour }})?</p>
</div>
<div class="modal-footer">
<div class="text-center">
<form method="POST">
{{ delete_form.csrf_token }}
<input id="delete_meeting" name="delete_meeting" type="hidden" value="{{ meeting.meeting_id }}">
{{ delete_form.submit(class="btn btn-danger") }}
</form>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
表格:
type_choices = [('training', 'Training'),('match', 'Match')]
pitch_choices = [('training_ground', 'Training Ground'), ('stadium', 'Stadium')]
class CreateMeetingForm(FlaskForm):
date = DateField('Date', validators=[DataRequired()])
hour = TimeField('Hour', validators=[DataRequired()])
type = SelectField('Type', choices=type_choices, validators=[DataRequired()])
locality = StringField('Locality', validators=[Length(min=2, max=20), DataRequired()])
pitch = SelectField('Pitch', choices=pitch_choices, validators=[DataRequired()])
submit = SubmitField('Create meeting!')
class UpdateMeetingForm(FlaskForm):
date = DateField('Date')
hour = TimeField('Hour')
type = SelectField('Type', choices=type_choices)
locality = StringField('Locality', validators=[Length(min=2, max=20)])
pitch = SelectField('Pitch', choices=pitch_choices)
submit = SubmitField('Update meeting!')
这是一个解决方案:
from flask import Flask, url_for, render_template_string
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'some_rndm_key'
class NameForm(FlaskForm):
name = StringField('Name')
submit = SubmitField('Submit Form')
class PhoneForm(FlaskForm):
phone = StringField('Phone')
submit = SubmitField('Submit Form')
@app.route('/')
@app.route('/<form>', methods=['GET', 'POST'])
def home(form=None):
name_form = NameForm()
phone_form = PhoneForm()
if form == 'name_form' and name_form.validate_on_submit():
return 'Submitted name form'
elif form == 'phone_form' and phone_form.validate_on_submit():
return 'Submitted phone form'
return render_template_string('<form method="POST" action="{{ url_for("home", form="name_form") }}">'
'{{ name_form.hidden_tag() }}'
'{{ name_form.name.label }}'
'{{ name_form.name }}'
'{{ name_form.submit }}'
'</form>'
'<br>'
'<form method="POST" action="{{ url_for("home", form="phone_form") }}">'
'{{ phone_form.hidden_tag() }}'
'{{ phone_form.phone.label }}'
'{{ phone_form.phone }}'
'{{ phone_form.submit }}'
'</form>', phone_form=phone_form, name_form=name_form)
app.run(debug=True)
基本上有一个带有变量的路由,在 <form>
标记中,您将操作指定为相同的路由,但添加到变量然后检查变量是什么,非常简单