我正在试验flask,只是创建一些基本功能以将数据添加到以模式显示的表单中。虽然我设法使表格显示在模态中并从模态中保存下来,但我仍在努力了解需要做什么以确保将字段验证错误显示在模态本身上。当前,如果出现错误,用户将使用编辑表单重定向到整个页面。
他们说图片胜于文字-所以这是一张gif,显示发生了什么事:
整个应用程序代码位于github上,并且可以访问here上的heroku当前状态...用户名: admin@admin.com 和密码: adminpassword 。反正都是沙盒。
相关代码如下:
routes.py
@expenses.route("/expense")
@login_required
def expense():
page = request.args.get('page', 1, type=int)
expenses = Expense.query.order_by(Expense.expense_date.desc()).paginate(page=page, per_page=5)
form = ExpenseForm()
return render_template('expense/expense.html', expenses=expenses, form=form)
@expenses.route("/expense/new", methods=['GET', 'POST'])
@login_required
def new_expense():
form = ExpenseForm()
if form.validate_on_submit():
expense = Expense(description=form.description.data, expense_date=form.expense_date.data,
amount=form.amount.data,vat_amount=form.vat_amount.data,Transferrable=form.Transferrable.data, author=current_user)
db.session.add(expense)
db.session.commit()
flash('Your expense has been created!', 'success')
return redirect(url_for('expenses.expense'))
return render_template('expense/create_expense.html', title='New Expense',
form=form, legend='New Expense')
现在expenses.html很大,但是在其上使用以下方式调用了模式:
<button type="button" class="btn btn-primary btn-sm m-1" data-toggle="modal" data-target="#AddNewModal">Add New Expense</button>
{% include "expense/partials/addModal.html" %}
和addModal.html如下所示:
<!-- Add New Modal -->
{% from "util/macros.html" import form_field with context %}
<div class="modal fade" id="AddNewModal" tabindex="-1" role="dialog" aria-labelledby="AddNewModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="AddNewModalLabel">Add New Expense</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="amount-section">
<form method="POST" action="/expense/new">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">{{ legend }}</legend>
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{% if form.description.errors %}
{{ form.description(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.description.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.description(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.amount.label(class="form-control-label") }}
{% if form.amount.errors %}
{{ form.amount(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.amount.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.amount(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.expense_date.label(class="form-control-label") }}
{% if form.expense_date.errors %}
{{ form.expense_date(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.expense_date.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.expense_date(class="form-control form-control-lg", type="date") }}
{% endif %}
</div>
<div class="form-group">
{{ form.vat_amount.label(class="form-control-label") }}
{% if form.vat_amount.errors %}
{{ form.vat_amount(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.vat_amount.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.vat_amount(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- {{ form_field(form.vat_amount,with_label=True) }} -->
<div class="form-group">
{% if form.Transferrable.errors %}
{{ form.Transferrable(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.Transferrable.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.Transferrable(type="checkbox") }}
{% endif %}
{{ form.Transferrable.label(class="form-control-label") }}
</div>
<!-- {{ form_field(form.Transferrable) }} -->
<p><button type="submit" class="btn btn-primary">Add</button></p>
</fieldset>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
答案 0 :(得分:1)
这是因为如果表单存在某些错误,您会渲染create_expense.html
,这就是为什么表单不以模式显示的原因。
我将合并两个视图:/expense/new
和/expense
,以便它可以处理GET
和POST
并在表单存在某些错误时有条件地显示模式。
合并视图:
@expenses.route("/expense", methods=['GET', 'POST'])
@login_required
def expense():
page = request.args.get('page', 1, type=int)
expenses = Expense.query.order_by(Expense.expense_date.desc()).paginate(page=page, per_page=5)
form = ExpenseForm()
if form.validate_on_submit():
expense = Expense(description=form.description.data, expense_date=form.expense_date.data,
amount=form.amount.data,vat_amount=form.vat_amount.data,Transferrable=form.Transferrable.data, author=current_user)
db.session.add(expense)
db.session.commit()
flash('Your expense has been created!', 'success')
return render_template('expense/expense.html', expenses=expenses, form=form)
在addModal.html
底部显示条件模式:
{% if form.errors %}
<script>
$('#AddNewModal').modal('show');
</script>
{% endif %}
并且addModal.html
中表单的操作也必须更改为:
<form method="POST" action="/expense">
但是,在这些更改之后,视图/expense/new
和/expense
会有一些共同的代码,因此可能需要重构。现在,您至少知道为什么错误不会在模态中显示。