防止用烧瓶重新提交确认表单
Prevent confirm form resubmission with flask
我有一个带有表单的烧瓶应用程序。当用户提交表单时,数据将被保存,并显示一条不同的消息来代替表单。当用户刷新页面时,我收到确认表单重新提交消息。我知道我需要使用重定向来避免这种情况,但我希望该站点是一个页面,所以我不想重定向到另一个页面。如果我重定向到 "/"
,那么它可以工作,但(如预期的那样)不会显示“谢谢”消息。是否可以将站点保持为单个页面,避免表单重新提交消息但仍显示感谢消息?
main.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
import forms
app = Flask(__name__)
app.config["SECRET_KEY"] = ""
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///test.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Booking(db.Model):
id = db.Column(db.Integer, primary_key=True)
first = db.Column(db.Text, nullable=False)
last = db.Column(db.Text, nullable = False)
telno = db.Column(db.Text, nullable=False)
message = db.Column(db.Text, nullable = False)
@app.route("/", methods = ["GET", "POST"])
def main():
filled = False
form = forms.BookingForm()
if form.validate_on_submit():
copy = dict(form.data)
del copy["submit"]
del copy["csrf_token"]
filled = True
db.session.add(Booking(**copy))
db.session.commit()
return render_template("formtest.html", form = form, filled = filled)
if __name__ == "__main__":
app.run(debug=True)
forms.py
from wtforms import validators
from wtforms.fields.html5 import TelField
from wtforms.validators import DataRequired
class BookingForm(FlaskForm):
first = StringField("First name", validators = [DataRequired()])
last = StringField("Last name", validators= [DataRequired()])
telno = TelField("Phone number", validators=[DataRequired()])
message = TextField("Please provide details of your appointment:", validators = [DataRequired()])
submit = SubmitField("Submit")
formtest.html
{% extends "base.html" %}
{% block head %}
<title>Booking form</title>
{% endblock %}
{% block body %}
{% if not filled %}
<form action = "/" method = "POST">
{{ form.hidden_tag() }}
<table>
<tr>
<td>{{ form.first.label }}</td>
<td>{{ form.last.label }}</td>
</tr>
<tr>
<td>{{ form.first() }}</td>
<td>{{ form.last() }}</td>
</tr>
<tr>
<td>{{ form.telno.label }}</td>
</tr>
<tr>
<td>{{ form.telno() }}</td>
</tr>
<tr>
<td>{{ form.message() }}</td>
</tr>
<tr>
<td>{{ form.submit() }}</td>
</tr>
</table>
</form>
{% else %}
<p>Thank you for your interest</p>
{% endif %}
{% endblock %}
您可以尝试像这样在重定向调用中传递填充的参数:
@app.route("/", methods = ["GET", "POST"])
def main():
form = forms.BookingForm()
filled = request.args.get('filled')
if filled is None:
filled = False
if form.validate_on_submit():
copy = dict(form.data)
del copy["submit"]
del copy["csrf_token"]
filled = True
db.session.add(Booking(**copy))
db.session.commit()
return redirect(url_for('main',filled=filled))
return render_template("formtest.html", form = form, filled = filled)
在您的 html 文件中添加以下脚本。
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
我有一个带有表单的烧瓶应用程序。当用户提交表单时,数据将被保存,并显示一条不同的消息来代替表单。当用户刷新页面时,我收到确认表单重新提交消息。我知道我需要使用重定向来避免这种情况,但我希望该站点是一个页面,所以我不想重定向到另一个页面。如果我重定向到 "/"
,那么它可以工作,但(如预期的那样)不会显示“谢谢”消息。是否可以将站点保持为单个页面,避免表单重新提交消息但仍显示感谢消息?
main.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
import forms
app = Flask(__name__)
app.config["SECRET_KEY"] = ""
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///test.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Booking(db.Model):
id = db.Column(db.Integer, primary_key=True)
first = db.Column(db.Text, nullable=False)
last = db.Column(db.Text, nullable = False)
telno = db.Column(db.Text, nullable=False)
message = db.Column(db.Text, nullable = False)
@app.route("/", methods = ["GET", "POST"])
def main():
filled = False
form = forms.BookingForm()
if form.validate_on_submit():
copy = dict(form.data)
del copy["submit"]
del copy["csrf_token"]
filled = True
db.session.add(Booking(**copy))
db.session.commit()
return render_template("formtest.html", form = form, filled = filled)
if __name__ == "__main__":
app.run(debug=True)
forms.py
from wtforms import validators
from wtforms.fields.html5 import TelField
from wtforms.validators import DataRequired
class BookingForm(FlaskForm):
first = StringField("First name", validators = [DataRequired()])
last = StringField("Last name", validators= [DataRequired()])
telno = TelField("Phone number", validators=[DataRequired()])
message = TextField("Please provide details of your appointment:", validators = [DataRequired()])
submit = SubmitField("Submit")
formtest.html
{% extends "base.html" %}
{% block head %}
<title>Booking form</title>
{% endblock %}
{% block body %}
{% if not filled %}
<form action = "/" method = "POST">
{{ form.hidden_tag() }}
<table>
<tr>
<td>{{ form.first.label }}</td>
<td>{{ form.last.label }}</td>
</tr>
<tr>
<td>{{ form.first() }}</td>
<td>{{ form.last() }}</td>
</tr>
<tr>
<td>{{ form.telno.label }}</td>
</tr>
<tr>
<td>{{ form.telno() }}</td>
</tr>
<tr>
<td>{{ form.message() }}</td>
</tr>
<tr>
<td>{{ form.submit() }}</td>
</tr>
</table>
</form>
{% else %}
<p>Thank you for your interest</p>
{% endif %}
{% endblock %}
您可以尝试像这样在重定向调用中传递填充的参数:
@app.route("/", methods = ["GET", "POST"])
def main():
form = forms.BookingForm()
filled = request.args.get('filled')
if filled is None:
filled = False
if form.validate_on_submit():
copy = dict(form.data)
del copy["submit"]
del copy["csrf_token"]
filled = True
db.session.add(Booking(**copy))
db.session.commit()
return redirect(url_for('main',filled=filled))
return render_template("formtest.html", form = form, filled = filled)
在您的 html 文件中添加以下脚本。
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>