问题 Python Flask-WTF - 使用相同的表单模板进行添加和编辑操作


我刚刚开始使用Flask / Flask-WTF / SQLAlchemy,我看到的大多数示例CRUD代码都显示了用于添加/编辑的单独模板。具有几乎相同的html形式的两个模板似乎是重复的(例如books_add.html,books_edit.html)。从概念上讲,对我来说更有意义的是有一个模板,比如“books_form.html”,只需从两个不同的路径定义中调用同一模板上的render_template。我不太确定如何实现它,例如:

@app.route('/books/add')
def add_book():
...
render_template('books_form.html', action = 'add')


@app.route('/books/edit/<id>')
def edit_book(id):
...
render_template('books_form.html', action = 'edit', id = id)

但我不确定我是否走上了正确的轨道,或者偏离了最佳实践。任何输入都很受欢迎 - 关于如何处理单个模板文件以处理添加或编辑行为的具体想法。也欢迎链接到示例。

谢谢!


8764
2018-05-25 19:03


起源



答案:


绝对没有理由使用单独的模板来添加/编辑不同类型的模板  甚至。考虑:

{# data.html #}
<!-- ... snip ... -->
{% block form %}
<section>
<h1>{{ action }} {{ data_type }}</h1>
<form action="{{ form_action }}" method="{{ method | d("POST") }}">
{% render_form(form) %}
</form>
</section>
{% endblock form %}

忽略宏 render_form 工作(在WTForms的文档中有一个示例) - 它只需要一个WTForms类型的对象,并将表单呈现在无序列表中。然后你可以这样做:

@app.route("/books/")
def add_book():
    form = BookForm()
    # ... snip ...
    return render_template("data.html", action="Add", data_type="a book", form=form)

@app.route("/books/<int:book_id>")
def edit_book(book_id):
    book = lookup_book_by_id(book_id)
    form = BookForm(obj=book)
    # ... snip ...
    return render_template("data.html", data_type=book.title, action="Edit", form=form)

但是你不需要仅限于书籍:

@app.route("/a-resource/")
def add_resource():
    # ... snip ...
    return render_template("data.html", data_type="a resource" ...)

# ... etc. ...

16
2018-05-26 01:32



谢谢!我不确定我是否理解render_form的引用 - 我回到WTForms文档和Quickstart,找不到它。我不能让它在我的代码中工作。我到达你要去的地方 - 你比我想的更抽象你的表格模板,我喜欢。也许如果你能详细说明那件特别的东西? - David
您可以使用jinja宏来渲染表单。看到 这个要点  - 你会看到的大部分代码都不是我的。该 render function只是一个非常通用的表单渲染器。像肖恩所说,如果你遵循这条路线,你需要将表格实例传递给模板。 - Teisman
谢谢!这有助于澄清。 - David


答案:


绝对没有理由使用单独的模板来添加/编辑不同类型的模板  甚至。考虑:

{# data.html #}
<!-- ... snip ... -->
{% block form %}
<section>
<h1>{{ action }} {{ data_type }}</h1>
<form action="{{ form_action }}" method="{{ method | d("POST") }}">
{% render_form(form) %}
</form>
</section>
{% endblock form %}

忽略宏 render_form 工作(在WTForms的文档中有一个示例) - 它只需要一个WTForms类型的对象,并将表单呈现在无序列表中。然后你可以这样做:

@app.route("/books/")
def add_book():
    form = BookForm()
    # ... snip ...
    return render_template("data.html", action="Add", data_type="a book", form=form)

@app.route("/books/<int:book_id>")
def edit_book(book_id):
    book = lookup_book_by_id(book_id)
    form = BookForm(obj=book)
    # ... snip ...
    return render_template("data.html", data_type=book.title, action="Edit", form=form)

但是你不需要仅限于书籍:

@app.route("/a-resource/")
def add_resource():
    # ... snip ...
    return render_template("data.html", data_type="a resource" ...)

# ... etc. ...

16
2018-05-26 01:32



谢谢!我不确定我是否理解render_form的引用 - 我回到WTForms文档和Quickstart,找不到它。我不能让它在我的代码中工作。我到达你要去的地方 - 你比我想的更抽象你的表格模板,我喜欢。也许如果你能详细说明那件特别的东西? - David
您可以使用jinja宏来渲染表单。看到 这个要点  - 你会看到的大部分代码都不是我的。该 render function只是一个非常通用的表单渲染器。像肖恩所说,如果你遵循这条路线,你需要将表格实例传递给模板。 - Teisman
谢谢!这有助于澄清。 - David