【问题标题】:Flask - Submit button submits all forms instead of one formFlask - 提交按钮提交所有表单而不是一个表单
【发布时间】:2018-10-27 20:19:35
【问题描述】:

我在我的一个页面中使用了两种表格,一种用于关闭工单,另一种用于发送回复。 但问题是当我提交其中一个时,另一个也提交了!并显示闪光按摩。所以我有两次闪光按摩! 这变得更加复杂,因为我正在检查一些条件以显示第一个表单,在这种情况下,该表单甚至不再出现,我有两个闪光按摩!

@app.route('/edit-ticket', methods=['GET', 'POST'])
def edit_ticket():
if session['logged_in'] == True:
    trackingNumberLink = int(request.args.get('trackingNumber'))
    closeForm = CloseTicket()
    editForm = EditTicket()
    GetTicketStatus = tickets.find_one({"trackingNumber": trackingNumberLink})
    if closeForm.validate_on_submit():
        tickets.update_one({"trackingNumber": trackingNumberLink},
                           {"$set": {"status": "پاسخ داده شده", "order": 2}})
        flash(u"تیکت مورد نظر با موفقیت بسته شد.")
    if editForm.validate_on_submit():
        replyDate = jdatetime.datetime.now()
        tickets.update_one({"trackingNumber": trackingNumberLink},
                           {"$set": {"status": "در حال بررسی", "order": 1}})
        tickets.update_one({"trackingNumber": trackingNumberLink},
                           {"$push": {"replies": {"rep": {"mass": editForm.ticketMassage.data,
                                                          "date": replyDate.strftime("%H:%M:%S %d-%m-%y "),
                                                          "HowSent": "user"}}}})
        flash(u"پاسخ با موفقیت ارسال شد.")
    return render_template('edit-ticket.html', Title="ویرایش تیکت", closeForm=closeForm,
                           editForm=editForm, CanUserCloseTicket=GetTicketStatus)
else:
    return redirect(url_for('Login'))

HTML:

{% extends "layout.html" %}
{% block content_main %}
<div class="container content-box">
    <div class="row">
        <div class="col-sm-12">
            <div class="FormSection center-form">
                <fieldset class="form-group">
                    <legend class="border-bottom mb-4">ویرایش تیکت</legend>
                </fieldset>
                <form method="post" action="">
                    {{ editForm.hidden_tag() }}
                    <div class="form-group">
                        {{ editForm.ticketMassage.label(class="form-control-label") }}
                        {% if editForm.ticketMassage.errors %}
                            {{ editForm.ticketMassage(class="form-control-lg is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in editForm.ticketMassage.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ editForm.ticketMassage(class="form-control-lg") }}
                        {% endif %}
                    </div>
                    <div class="form-group">
                        {{ editForm.submit(class="btn btn-outline-info") }}
                    </div>
                </form>
            </div>
            {% if CanUserCloseTicket['status'] != "پاسخ داده شده" %}
                <div class="FormSection center-form">
                    <form method="post" action="">
                        {{ closeForm.hidden_tag() }}
                        <div class="form-group">
                            {{ closeForm.submitCloseTicket(class="btn btn-outline-info") }}
                        </div>
                    </form>
                </div>
            {% endif %}
        </div>
    </div>
</div>
</div>
{% endblock content_main %}

表单类:

class EditTicket(FlaskForm):
    ticketMassage = TextAreaField('متن پیام:',
                              description=u'پاسخ خود را بنویسید.',
                              validators=[data_required(), Length(min=20, max=500)], )
    submit = SubmitField('ویرایش تیکت')


class CloseTicket(FlaskForm):
    submitCloseTicket = SubmitField('بستن تیکت')

【问题讨论】:

    标签: python html flask flask-wtforms wtforms


    【解决方案1】:

    使用 id 属性渲染表单标签,并为提交和输入标签使用表单属性。

    <form id="edit-ticket">
        {{ form.submit(form="edit-ticket") }}
    

    与输入元素关联的表单元素(其表单所有者)。属性的值必须是同一文档中元素的 id。如果不使用此属性,则该元素将与其最近的祖先元素相关联(如果有)。此属性允许您将元素放置在文档中的任何位置,而不仅仅是作为表单元素的后代。

    更新submit 使用不同的名称,然后在您的views.py if close_form.validate_on_submit() and close_form.close.data: 中使用不同的名称

    from flask import Flask, render_template
    from flask_wtf import FlaskForm, CSRFProtect
    from wtforms.fields import SubmitField, TextAreaField
    
    app = Flask(__name__)
    
    
    app.config['SECRET_KEY'] = '^%huYtFd90;90jjj'
    app.config['UPLOADED_FILES'] = 'static/files'
    
    
    csrf = CSRFProtect(app)
    
    
    class EditTicketForm(FlaskForm):
        ticket_message = TextAreaField()
        edit = SubmitField()
    
    
    class CloseTicketForm(FlaskForm):
        message = TextAreaField()
        close = SubmitField()
    
    
    @app.route('/edit-ticket', methods=['GET', 'POST'])
    def edit_ticket():
        close_form = CloseTicketForm()
        edit_form = EditTicketForm()
        if close_form.is_submitted() and close_form.close.data:
            if close_form.validate():
                x = close_form.message.data
                return x.upper()
        if edit_form.is_submitted() and edit_form.edit.data:
            if edit_form.validate():
                y = edit_form.ticket_message.data
                return y.upper()
        return render_template('edit-ticket.html', close_form=close_form, edit_form=edit_form)
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    edit-ticket.html

    <form method="post" id="edit-form" novalidate></form>
    <form method="post" id="close-form" novalidate></form>
        {{ edit_form.csrf_token(form="edit-form") }}
        {{ close_form.csrf_token(form="close-form") }}
        {{ edit_form.ticket_message(form="edit-form") }}
        {{ edit_form.edit(form="edit-form") }}
        {{ close_form.message(form="close-form") }}
        {{ close_form.close(form="close-form") }}
    

    【讨论】:

    • 嗨,罗伊,感谢您的回复。我已经尝试过您的建议并添加了两个表单并提交了底部,但我仍然遇到同样的问题。
    • 表单元素也应该有form=""属性`
    • 我照你说的做了,但还是没有运气。看,当我提交一个表单时,它也会进入另一个表单 validate_on_submit() 条件,这就是为什么我有两个 flash 消息,因为在某些情况下我在页面中没有两个表单!
    • 我已经更新了答案,if close_form.validate_on_submit() and close_form.close.data: 解决了这个问题。
    • 非常感谢您的更新。问题解决了。但我仍然有一点冲突:当我在我的页面中准备好两个表单并单击关闭票时,它会检查编辑票表并给我验证错误!截图:uupload.ir/files/xmh3_capture.png
    【解决方案2】:

    在您的表单上添加一个操作,而不是将其留空:

    <form method="post" action="/close-ticket"> ... </form>
    
    <form method="post" action="/edit-ticket"> ... </form>
    

    定义显式函数来处理每个动作。一项操作,一项功能 - 保持简单。拆分并重新使用每个登录的逻辑。

    @app.route('/close-ticket', methods=['POST'])
    def close_ticket():
        if session['logged_in'] != True:
            return redirect(url_for('Login'))
        # closeForm handling, etc....
    
    @app.route('/edit-ticket', methods=['POST'])
    def edit_ticket():
        if session['logged_in'] != True:
            return redirect(url_for('Login'))
        # editForm handling, etc....
    

    【讨论】:

    • 感谢您的回复。感谢您的帮助,但我需要一页和一页的表格。你写的这个例子工作得很好,但不是我的情况。
    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 2017-04-26
    • 2016-01-11
    • 2014-03-23
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    相关资源
    最近更新 更多