Fügen Sie mit Flask-WTF/WTForms eine Abbrechen-Schaltfläche in Flask hinzu

Aug 16 2020

Ich möchte eine Abbrechen-Schaltfläche hinzufügen, die zur vorherigen Seite zurückkehrt. Mein Code ist: 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')

und Vorlagenseite:

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

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

Ich erhalte einen 405-Fehler, wenn ich auf die Schaltfläche „Abbrechen“ klicke: Methode nicht zulässig.

Wo ist mein Fehler? und was muss ich hinzufügen, damit ich zur vorherigen Seite zurückkehre, wenn ich auf „Abbrechen“ klicke?

Danke

Antworten

baldy Sep 16 2020 at 10:12

Nein, ich verwende das TimeField, um die Erfassung einer gültigen Uhrzeit zu erzwingen. Ich habe nicht versucht, dies in ein normales Textfeld zu ändern, also habe ich stattdessen die Option Link abbrechen oben gewählt. Ich bevorzuge jedoch immer noch eine Abbrechen-Schaltfläche.

3 GreyLi Aug 17 2020 at 13:19

Ich erhalte einen 405-Fehler, wenn ich auf die Schaltfläche „Abbrechen“ klicke: Methode nicht zulässig. Wo ist mein Fehler?

Wenn Sie das Formular absenden, werden die Daten als POST-Anforderung gesendet (da das gerenderte Formularelement <form method="post">) verwendet. Ihre Ansichtsfunktion lässt jedoch standardmäßig nur GET-Anforderungen zu. Um POST-Anforderungen zu akzeptieren, müssen Sie den methodsParameter wie folgt angeben:

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

und was muss ich hinzufügen, damit ich zur vorherigen Seite zurückkehre, wenn ich auf „Abbrechen“ klicke?

Jedes mit erstellte Feld SubmitFieldwird als Senden-Schaltfläche ( <input type="submit">) gerendert, sodass das Formular gesendet wird, wenn Sie darauf klicken.

Damit es beim Klicken auf die Schaltfläche „Abbrechen“ zur vorherigen Seite zurückkehrt, gibt es normalerweise zwei Methoden, um dies zu erreichen:

1. Klicken Sie auf die Funktion zum Senden der Ansicht

Wie die Methode in Bens Antwort . Sie können einfach die Übermittlung abfangen und den Benutzer dann zur vorherigen Seite weiterleiten:

@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 Da Sie bereits in gesetzt haben novalidate=True, wtf.quick_formmüssen Sie in der Formularklasse nicht render_kw={'formnovalidate': True}auf die cancelSchaltfläche setzen.

2. Erstellen Sie eine <a>Schaltfläche anstelle eines cancelFelds

Sie können ein normales <a>Element als Abbrechen-Schaltfläche ( class="btn btn-secondary") erstellen und den Parameter mit der URL der vorherigen Seite füllen (dann müssen Sie Ihrer Formularklasse hrefkein Feld hinzufügen ). cancelAuf diese Weise können Sie nicht verwenden wtf.quick_form(), stattdessen müssen Sie jedes Feld manuell mit rendern 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

So funktioniert das bei mir.

In meiner Form...

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

In meinem Python-Code (in Ihrem Fall views.py) ...

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

Last-Minute-Änderung: Der Hinweis von Gray Li unten, wie Sie Ihrer Ansichtsfunktion erlauben, POST-Anforderungen zu akzeptieren, ist ebenfalls wichtig. Stellen Sie sicher, dass Sie es überprüfen.