“ form.populate_by返回”错误:“列表”对象没有属性

时间:2019-03-30 10:40:04

标签: flask flask-sqlalchemy flask-wtforms

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

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

数据库模型:

bulk insert tablename from 'C:\test.csv' with (rowterminator = '\n',fieldterminator = ',',KEEPIDENTITY)

表单模型:

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()

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

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')]

该错误表明,每个字段都需要2个部分“ framefield.populate_obj(obj,name)”,我的字段仅提供一个列数据,但不提供列名称“ sensorID” 如果我在“ edit = ...”行中散列#,则没有错误消息,并且返回了表单,但字段为空。因此,我希望将表单与数据库中的信息一起返回,并进行填写,以便我可以修改名称或sensorID,然后更新数据库。

我希望这很清楚

亲切的问候

保罗。

ps我已按照指示进行操作,因此ERROR语句仅是“ field.populate_by”之后的部分。

1 个答案:

答案 0 :(得分:1)

您正在尝试将一个1项列表传递给表单。

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

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

Form.validate_on_submit仅在您的请求方法为POST并且您的表单通过验证时才返回True。这是您的表单告诉您“用户在语法上提供了正确信息的步骤,现在您可以进行更多检查,并且我可以使用提供给我的数据填充现有对象”。

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

@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)