Tambahkan tombol batal di Flask dengan Flask-WTF / WTForms

Aug 16 2020

Saya ingin menambahkan tombol batal yang kembali ke halaman sebelumnya. Kode saya adalah: 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')

dan halaman template:

{% 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 %}

dilihat, 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)

Saya mengalami kesalahan 405 ketika saya mengklik tombol batal: Metode tidak diizinkan.

Dimana kesalahan saya? dan apa yang harus saya tambahkan untuk kembali ke halaman sebelumnya ketika saya mengklik Batal?

Terima kasih

Jawaban

baldy Sep 16 2020 at 10:12

Tidak, saya menggunakan TimeField untuk memaksakan pengambilan Time yang valid. Saya belum mencoba mengubahnya ke bidang teks normal, jadi gunakan opsi Batalkan tautan di atas sebagai gantinya. Preferensi saya tetap memiliki tombol Batal.

3 GreyLi Aug 17 2020 at 13:19

Saya mengalami kesalahan 405 ketika saya mengklik tombol batal: Metode tidak diizinkan. Dimana kesalahan saya?

Saat Anda mengirimkan formulir, data akan dikirim sebagai permintaan POST (karena elemen formulir yang dirender akan digunakan <form method="post">). Namun, fungsi tampilan Anda hanya mengizinkan permintaan GET sebagai default, untuk menerima permintaan POST, Anda harus menetapkan methodsparameter seperti ini:

@orgs.route('/organisations/org_new', methods=['GET', 'POST'])  # <--
@login_required
def org_new():
   # ...

dan apa yang harus saya tambahkan untuk kembali ke halaman sebelumnya ketika saya mengklik Batal?

Setiap bidang yang dibuat dengan SubmitFieldakan dirender sebagai tombol kirim ( <input type="submit">), sehingga formulir akan dikirim saat Anda mengkliknya.

Untuk membuatnya kembali ke halaman sebelumnya ketika Anda mengklik tombol batal, biasanya ada dua metode untuk mencapai ini:

1. Menangkap tombol kirim dalam fungsi tampilan

Seperti metode dalam jawaban Ben . Anda tinggal menangkap kiriman lalu mengarahkan pengguna ke halaman sebelumnya:

@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 Karena Anda telah mengatur novalidate=Truedi wtf.quick_form, Anda tidak perlu set render_kw={'formnovalidate': True}padacancel tombol di kelas bentuk.

2. Buat <a>tombol alih-alih cancelbidang

Anda dapat membuat <a>elemen normal sebagai tombol batal ( class="btn btn-secondary") dan mengisi hrefparameter dengan URL halaman sebelumnya (maka Anda tidak perlu menambahkan cancelbidang di kelas formulir Anda). Dengan cara ini, Anda tidak dapat menggunakan wtf.quick_form(), sebagai gantinya Anda harus merender setiap bidang secara manual dengan 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>
3 Ben Aug 17 2020 at 08:06

Begini cara kerjanya untuk saya.

Dalam wujudku ...

btn_cancel = SubmitField(label='Cancel',
                         render_kw={'formnovalidate': True})

Dalam kode Python saya (views.py dalam kasus Anda) ...

if request.method == 'POST':
    if form.btn_cancel.data:
        return redirect(url_for('data'))

Pengeditan menit terakhir: Catatan Gray Li di bawah tentang mengizinkan fungsi tampilan Anda untuk menerima permintaan POST juga penting. Pastikan Anda memeriksanya.