You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQLAlchemy更新数据无法commit,报NoneType无rating属性错误

问题原因分析
  • 核心原因是POST请求时视图函数未获取到有效的电影ID,导致Movie.query.filter_by(id=movie_id).first()返回None,后续对None访问rating属性触发报错,事务直接中断所以没有修改数据库。
  • 具体触发逻辑:你在GET请求进入编辑页时,是通过URL参数id获取要编辑的电影ID,但前端提交表单时,form标签的action没有携带该ID参数,导致POST请求到达视图函数时,request.args.get('id')返回空值,无法查询到对应电影记录。
  • 额外隐患:当前代码没有做查询结果非空判断,只要ID无效就会直接抛出属性错误,缺少异常兜底逻辑。
解决步骤

方法1:在表单提交路径中携带ID参数(改动最小)

  1. 修改编辑页视图函数,添加异常兜底并将电影ID传递到前端:
from flask import abort

@app.route('/edit', methods=['GET','POST'])
def edit_movie():
    movie_id = request.args.get('id')
    # ID不存在直接返回404,避免后续逻辑出错
    if not movie_id:
        abort(404)
    form = Edit_Form()
    print(movie_id)

    if request.method == 'POST':
        # 改用get_or_404,查不到对应电影直接返回404,不会触发属性错误
        movie_update = Movie.query.get_or_404(movie_id)
        movie_update.rating = form.rating.data
        movie_update.review = form.review.data
        db.session.commit()
        return redirect(url_for('home'))
    # 把movie_id传递给前端模板
    return render_template('edit.html', form=form, movie_id=movie_id)
  1. 修改前端form的action属性,提交时携带ID参数:
<form action="{{ url_for('edit_movie', id=movie_id) }}" method="POST">
{{ form.csrf_token }}
<p>请输入新的评分</p>
{{ form.rating }}
<p>请填写你的影评 </p>
{{ form.review }}
{{ form.submit }}
</form>

方法2:使用表单隐藏字段传递ID(更规范)

  1. 在Edit_Form表单类中新增ID隐藏字段:
from wtforms import HiddenField

class Edit_Form(FlaskForm):
    # 原有rating、review、submit等字段保持不变
    id = HiddenField('id')
  1. 修改视图函数,直接通过表单传递ID:
from flask import abort

@app.route('/edit', methods=['GET','POST'])
def edit_movie():
    movie_id = request.args.get('id')
    if not movie_id:
        abort(404)
    # 实例化表单时直接给id隐藏字段赋值
    form = Edit_Form(id=movie_id)
    if request.method == 'POST':
        # POST请求时从表单字段获取ID,不依赖URL参数
        movie_update = Movie.query.get_or_404(form.id.data)
        movie_update.rating = form.rating.data
        movie_update.review = form.review.data
        db.session.commit()
        return redirect(url_for('home'))
    return render_template('edit.html', form=form)
  1. 前端代码无需额外改动,表单会自动渲染隐藏的ID字段,提交时自动携带参数。

内容的提问来源于stack exchange,提问作者יבגני ברשדסקי

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:15:03