Agregue un botón de cancelación en Flask con Flask-WTF/WTForms
Me gustaría agregar un botón de cancelar que regrese a la página anterior. Mi código es: formularios.py:
from flask_wtf import Form
from wtforms import StringField, HiddenField, SubmitField
from wtforms.validators import DataRequired, Length, ValidationError
def _required(form, field):
if not field.raw_data or not field.raw_data[0]:
raise ValidationError('Field is required')
class OrganisationForm(Form):
id = HiddenField('id', default="-1")
name = StringField('name', validators=[DataRequired()])
manager_name = StringField('manager_name')
address = StringField('address', validators=[DataRequired()])
city = StringField('city', validators=[DataRequired()])
postal_code = StringField('postal_code', validators=[DataRequired(), Length(max=16)])
province = StringField('province', validators=[Length(max=2, message="Can't exceed 2 characters")])
country = StringField('country', validators=[DataRequired()])
submit = SubmitField('Add')
cancel = SubmitField('Cancel')
y página de plantilla:
{% block content %}
<div class="content-section">
{{ utils.flashed_messages() }}
<div class="center">
{% if add_orgnisation %}
<h1>add an organisation</h1>
{% else %}
<h1>Edit an organisation</h1>
{% endif %}
<br/>
<br/>
{{ wtf.quick_form(form,novalidate=True) }}
</div>
</div>
{% endblock %}
vistas
@orgs.route('/organisations/org_new')
@login_required
def org_new():
add_orgnisation = True
form = OrganisationForm()
return render_template("organisations/organisation_form.html", form=form, title="New Organisation", edit=False, add_orgnisation=add_orgnisation)
Tengo un error 405 cuando hago clic en el botón cancelar: Método no permitido.
¿Dónde está mi error? y ¿qué debo agregar para volver a la página anterior cuando hago clic en Cancelar?
Gracias
Respuestas
No, estoy usando TimeField para forzar la captura de un tiempo válido. No he intentado cambiar eso a un campo de texto normal, así que opté por la opción Cancelar enlace de arriba. Sin embargo, mi preferencia sigue siendo tener un botón Cancelar.
Tengo un error 405 cuando hago clic en el botón cancelar: Método no permitido. ¿Dónde está mi error?
Cuando envíe el formulario, los datos se enviarán como una solicitud POST (porque el elemento del formulario representado utilizará <form method="post">
). Sin embargo, su función de vista solo permite la solicitud GET de forma predeterminada, para aceptar la solicitud POST, debe especificar el methods
parámetro de esta manera:
@orgs.route('/organisations/org_new', methods=['GET', 'POST']) # <--
@login_required
def org_new():
# ...
y ¿qué debo agregar para volver a la página anterior cuando hago clic en Cancelar?
Cualquier campo creado con SubmitField
se representará como un botón de envío ( <input type="submit">
), por lo que enviará el formulario cuando haga clic en él.
Para hacer que regrese a la página anterior cuando hace clic en el botón cancelar, normalmente hay dos métodos para lograrlo:
1. Atrapa el botón enviar en la función de vista
Como el método en la respuesta de Ben . Puede capturar el envío y luego redirigir al usuario a la página anterior:
@orgs.route('/organisations/org_new', methods=['GET', 'POST'])
@login_required
def org_new():
if request.method == 'POST':
if form.cancel.data: # if cancel button is clicked, the form.cancel.data will be True
return redirect(url_for('previous_page_view_name'))
# ...
PD Como ya lo ha configurado novalidate=True
, wtf.quick_form
no necesita configurar render_kw={'formnovalidate': True}
el cancel
botón en la clase de formulario.
2. Crea un <a>
botón en lugar de un cancel
campo
Puede crear un <a>
elemento normal como botón de cancelación ( class="btn btn-secondary"
) y completar el href
parámetro con la URL de la página anterior (entonces no necesita agregar un cancel
campo en su clase de formulario). De esta manera, no puede usar wtf.quick_form()
, en su lugar, deberá representar cada campo manualmente con wtf.form_field()
:
<form method="post">
{{ wtf.form_field(form.id) }}
{{ wtf.form_field(form.name) }}
{{ wtf.form_field(form.manager_name) }}
{{ wtf.form_field(form.address) }}
...
{{ wtf.form_field(form.submit) }}
<a href="{{ url_for('previous_page_view_name') }}" class="btn btn-secondary">Cancel</a>
</form>
Así es como esto funciona para mí.
En mi forma...
btn_cancel = SubmitField(label='Cancel',
render_kw={'formnovalidate': True})
En mi código de Python (views.py en su caso)...
if request.method == 'POST':
if form.btn_cancel.data:
return redirect(url_for('data'))
Edición de última hora: la nota de Gray Li a continuación sobre permitir que su función de vista acepte solicitudes POST también es importante. Asegúrate de comprobarlo.