如何通过Jinja模板引擎向WTForms传递discussion_id并设置表单值?
问题解决步骤
1. 修复数据库查询问题
你的视图中用filter返回的是查询对象,不是单个讨论实例,无法直接访问title/text属性。改用get_or_404直接获取对应ID的实例,不存在时返回404页面:
@blueprint.route("/community/discussions/<int:discussion_id>/update", methods=["POST", "GET"]) @login_required def update_discussion(discussion_id): # 替换原查询语句 discussion = Discussions.query.get_or_404(discussion_id) # ... 后续代码
2. 正确设置表单初始值
在GET请求初始化表单时,通过obj参数直接绑定数据库实例(要求模型字段名与表单字段名一致,你的代码满足这个条件),自动填充初始值:
else: # 用obj绑定discussion实例,自动填充字段初始值 form = DiscussionForm(obj=discussion) return render_template("discussions.html", discussion=discussion, form=form)
如果需要单独设置字段,也可以用data参数:
form = DiscussionForm( data={ "title": discussion.title, "text": discussion.text } )
3. 修正模板中的错误
3.1 修复表单渲染语法
模板中不能嵌套Jinja表达式({{ form.text({{ discussion.text }}) }}是错误写法),直接渲染字段即可,初始值已在视图中设置:
3.2 修正表单提交地址
表单action应指向当前更新路由,而非创建路由;同时hidden_tag()只需在表单开头写一次即可:
<div style="background-color:black; border: solid white 1px; "> <form action="{{ url_for('discussions.update_discussion', discussion_id=discussion.id) }}" method="POST"> {{ form.hidden_tag() }} <div> {{ form.title() }} </div> <div style="margin-top: 10px;"> {{ form.text() }} </div> <div> {{ form.submit() }} </div> </form> </div>
4. 完善POST请求的更新逻辑
原POST请求中直接给查询对象赋值无效,需要对已获取的discussion实例更新:
if request.method == "POST": form = DiscussionForm(request.form) if form.validate_on_submit(): # 直接更新discussion实例的属性 discussion.title = form.title.data discussion.text = form.text.data try: db.session.commit() flash("讨论更新成功") except Exception as e: db.session.rollback() flash(f"Произошла ошибка: {str(e)}") return redirect(url_for("community.community_page")) # ... 错误提示代码
可选优化:表单字段类型
你的text字段用StringField加TextArea widget,可直接改用WTForms的TextAreaField更规范:
from wtforms import TextAreaField class DiscussionForm(FlaskForm): # ... 其他字段 text = TextAreaField("Text", validators=[DataRequired()], render_kw={"class": "form-text", "placeholder": "Ваше сообщение"}) # ...
内容的提问来源于stack exchange,提问作者wicki77
相关产品推荐
相关产品推荐

