Dodaj przycisk anulowania w Flask z Flask-WTF / WTForms
Chciałbym dodać przycisk anulowania, który powoduje powrót do poprzedniej strony. Mój kod to: forms.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')
i strona szablonu:
{% 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 %}
widoki, py
@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)
Po kliknięciu przycisku anulowania pojawia się błąd 405: Metoda niedozwolona.
Gdzie jest mój błąd? a co powinienem dodać, aby wrócić do poprzedniej strony po kliknięciu przycisku Anuluj?
dzięki
Odpowiedzi
Nie, używam TimeField do wymuszenia przechwytywania prawidłowego czasu. Nie próbowałem zmienić tego na zwykłe pole tekstowe, więc zamiast tego skorzystałem z opcji Anuluj link powyżej. Jednak nadal wolę mieć przycisk Anuluj.
Po kliknięciu przycisku anulowania pojawia się błąd 405: Metoda niedozwolona. Gdzie jest mój błąd?
When you submit the form, the data will be sent as a POST request (because the rendered form element will use <form method="post">
). However, your view function only allow GET request as default, to accept POST request, you have to specified the methods
parameter like this:
@orgs.route('/organisations/org_new', methods=['GET', 'POST']) # <--
@login_required
def org_new():
# ...
and what should I add to have a go back previous page when I click on Cancel?
Any field created with SubmitField
will rendered as a submit button (<input type="submit">
), so it will submit the form when you click it.
To make it go back to the previous page when you click the cancel button, there are normally two methods to achieve this:
1. Catch the button submit in view function
Like the method in Ben's answer. You can just catch the submit then redirect the user to previous page:
@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'))
# ...
PS Skoro masz już ustawione novalidate=True
w wtf.quick_form
, nie trzeba ustawić render_kw={'formnovalidate': True}
na cancel
przycisk w klasie formularza.
2. Utwórz <a>
przycisk zamiast cancel
pola
Możesz utworzyć zwykły <a>
element jako przycisk anulowania ( class="btn btn-secondary"
) i wypełnić href
parametr adresem URL poprzedniej strony (wtedy nie musisz dodawać cancel
pola w swojej klasie formularza). W ten sposób nie możesz użyć wtf.quick_form()
, zamiast tego będziesz musiał renderować każde pole ręcznie za pomocą 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>
Oto jak to działa w moim przypadku.
W mojej formie ...
btn_cancel = SubmitField(label='Cancel',
render_kw={'formnovalidate': True})
W moim kodzie Pythona (w twoim przypadku views.py) ...
if request.method == 'POST':
if form.btn_cancel.data:
return redirect(url_for('data'))
Edycja z ostatniej chwili: Ważna jest również uwaga Graya Li poniżej o zezwoleniu funkcji widoku na akceptowanie żądań POST. Koniecznie sprawdź to.