เพิ่มปุ่มยกเลิกใน Flask ด้วย Flask-WTF / WTForms

Aug 16 2020

ฉันต้องการเพิ่มปุ่มยกเลิกซึ่งจะกลับไปที่หน้าก่อนหน้านี้ รหัสของฉันคือ: form.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')

และหน้าเทมเพลต:

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

มุมมอง 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)

ฉันมีข้อผิดพลาด 405 เมื่อฉันคลิกที่ปุ่มยกเลิก: ไม่อนุญาตวิธีการ

ความผิดพลาดของฉันอยู่ที่ไหน และสิ่งที่ฉันควรเพิ่มเพื่อให้ย้อนกลับไปก่อนหน้านี้เมื่อฉันคลิกที่ยกเลิก?

ขอบคุณ

คำตอบ

baldy Sep 16 2020 at 10:12

ไม่ฉันใช้ TimeField เพื่อบังคับใช้การบันทึกเวลาที่ถูกต้อง ฉันยังไม่ได้ลองเปลี่ยนเป็นช่องข้อความปกติเลยใช้ตัวเลือกยกเลิกลิงค์ด้านบนแทน ความชอบของฉันยังคงมีปุ่มยกเลิกอยู่

3 GreyLi Aug 17 2020 at 13:19

ฉันมีข้อผิดพลาด 405 เมื่อฉันคลิกที่ปุ่มยกเลิก: ไม่อนุญาตวิธีการ ความผิดพลาดของฉันอยู่ที่ไหน

เมื่อคุณส่งแบบฟอร์มข้อมูลจะถูกส่งเป็นคำขอ POST (เนื่องจากจะใช้องค์ประกอบฟอร์มที่แสดงผล<form method="post">) อย่างไรก็ตามฟังก์ชั่นมุมมองของคุณอนุญาตเฉพาะคำขอ GET เป็นค่าเริ่มต้นเพื่อยอมรับคำขอ POST คุณต้องระบุmethodsพารามิเตอร์ดังนี้:

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

และสิ่งที่ฉันควรเพิ่มเพื่อให้ย้อนกลับไปก่อนหน้านี้เมื่อฉันคลิกที่ยกเลิก?

ฟิลด์ใด ๆ ที่สร้างด้วยSubmitFieldจะแสดงผลเป็นปุ่มส่ง ( <input type="submit">) ดังนั้นฟิลด์จะส่งแบบฟอร์มเมื่อคุณคลิก

หากต้องการย้อนกลับไปยังหน้าที่แล้วเมื่อคุณคลิกปุ่มยกเลิกโดยปกติมีสองวิธีในการดำเนินการนี้

1. จับปุ่มส่งในฟังก์ชั่นมุมมอง

เช่นเดียวกับวิธีการในคำตอบของเบ็น คุณสามารถจับการส่งจากนั้นเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าที่แล้ว:

@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 เนื่องจากคุณได้กำหนดไว้แล้วnovalidate=Trueในการwtf.quick_formที่คุณไม่จำเป็นต้องตั้งrender_kw={'formnovalidate': True}อยู่บนcancelปุ่มในชั้นเรียนแบบฟอร์ม

2. สร้าง<a>ปุ่มแทนcancelฟิลด์

คุณสามารถสร้าง<a>องค์ประกอบปกติเป็นปุ่มยกเลิก ( class="btn btn-secondary") และกรอกhrefพารามิเตอร์ด้วย URL ของหน้าก่อนหน้า (จากนั้นคุณไม่จำเป็นต้องเพิ่มcancelฟิลด์ในคลาสฟอร์มของคุณ) ด้วยวิธีนี้คุณไม่สามารถใช้ได้wtf.quick_form()แต่คุณจะต้องแสดงผลแต่ละฟิลด์ด้วยตนเองด้วย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

นี่คือวิธีการทำงานสำหรับฉัน

ในรูปแบบของฉัน ...

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

ในรหัส Python ของฉัน (views.py ในกรณีของคุณ) ...

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

การแก้ไขในนาทีสุดท้าย: หมายเหตุของ Grey Li ด้านล่างเกี่ยวกับการอนุญาตให้ฟังก์ชันมุมมองของคุณยอมรับคำขอ POST ก็มีความสำคัญเช่นกัน ตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบแล้ว