"form.populate_by returns" ERROR:'list' object has no attribute

"form.populate_by returns" ERROR:'list' object has no attribute

我正在创建一个视图函数来使用 wtform 编辑数据库,我想用不同表单提供的数据库中保存的信息填充表单,我的问题是提供详细信息的查询

我已阅读手册https://wtforms.readthedocs.io/en/stable/crash_course.html 以及以下问题 Python Flask-WTF - use same form template for add and edit operations 但我的查询似乎没有提供正确的数据格式

数据库模型:

class Sensors(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sensorID = db.Column(db.String, unique=True)
    name = db.Column(db.String(30), unique=True)

表单模型:

class AddSensorForm(FlaskForm):
    sensorID = StringField('sensorID', validators=[DataRequired()])
    sensorName = StringField('sensorName', validators=[DataRequired()])
    submit = SubmitField('Register')

查看功能:

@bp.route('/sensors/editsensor/<int:id>', methods=('GET', 'POST'))
@login_required
def editsensor(id):
    edit = [(s.sensorID, s.sensorName) for s in db.session.\
      query(Sensors).filter_by(id=id).all()]
    form = AddSensorForm(obj=edit)
    form.populate_obj(edit)
    if form.validate_on_submit():
        sensors = Sensors(sensorID=form.sensorID.data, sensorName=form.sensorNa$
        db.session.add(sensors)
        db.session.commit()

shell查询代码:

from homeHeating import db
from homeHeating import create_app
app = create_app()
app.app_context().push()
def editsensor(id):
    edit = [(s.sensorID, s.sensorName) for s in db.session.query(Sensors).filter_by(id=id).all()]
    print(edit)

editsensor(1)
[('28-0000045680fde', 'Boiler input')]

我希望这两个表单字段将填充有关其 'id' 调用的传感器的信息 但是我得到这个错误

File "/home/pi/heating/homeHeating/sensors/sensors.py", line 60, in 
editsensor
form.populate_obj(edit)
File "/home/pi/heating/venv/lib/python3.7/site- 
packages/wtforms/form.py", line 96, in populate_obj
Open an interactive python shell in this 
framefield.populate_obj(obj, name)
File "/home/pi/heating/venv/lib/python3.7/site- 
packages/wtforms/fields/core.py", line 330, in populate_obj
setattr(obj, name, self.data)
AttributeError: 'list' object has no attribute 'sensorID'

错误表明每个字段需要 2 个部分 "framefield.populate_obj(obj, name) mine provides only one the column data but not the column name, "sensorID" 如果我散列 # 行 "edit = ..." 则没有错误消息并且返回表单但字段为空。所以我希望表单返回数据库中的信息,填写后我可以修改名称或 sensorID,然后更新数据库。

我希望这是清楚的

热烈的问候

保罗.

ps我已经按照说明操作了,所以ERROR语句只是"field.populate_by"之后的部分。

您正在尝试将 1 项列表传递到您的表单。

通常,当您根据模型的主键选择单个记录时,使用 Query.get() 而不是 Query.filter(...).all()[0] .

此外,您需要将请求数据传递到您的表单以在提交时对其进行验证,并在表单报告错误时预先填写字段。

Form.validate_on_submit 只有在您的请求方法是 POST 并且您的表单通过验证时才会 return 为真;这是您的表格告诉您 "the user provided syntactically correct information, now you may do more checks and I may populate an existing object with the data provided to me".

的步骤

您还需要处理首次向用户显示表单的情况。

@bp.route('/sensors/editsensor/<int:id>', methods=('GET', 'POST'))
@login_required
def editsensor(id):
    obj = Sensors.query.get(id) or Sensors()
    form = AddSensorForm(request.form, obj=obj)

    if form.validate_on_submit():
        form.populate_obj(obj)
        db.session.add(obj)
        db.session.commit()

        # return response or redirect here
        return redirect(...)

    else:
        # either the form has errors, or the user is displaying it for
        # the first time (GET)

        return render_template('sensors.html', form=form, obj=obj)