【问题标题】:SQLalchemy update data in SQlite using wtformsSQLalchemy 使用 wtforms 更新 SQlite 中的数据
【发布时间】:2023-03-27 05:33:01
【问题描述】:

大家好,

我在使用 wtforms、SQLAlchemy 和 SQlite3 编辑数据时遇到问题。我已经生成了一个表单,可以查询到按ID过滤的数据。该表格完美地填充了相应的数据。但是当我更改数据并按提交时,它不会更新数据。其实有两个问题。首先,表单不会将新类型的数据传递回 python 和变量,其次我不知道如何更新当前选定的数据行。

这是我的代码:

@app.route('/sensorlist_edit/<string:id>', methods=['GET', 'POST'])
@is_logged_in
def sensorlist_edit(id):
    sensor = Sensor.query.filter_by(id=id).first()
    form = SensorListForm(request.form)
    form.name.data = sensor.name
    form.sensor_type.data = str(sensor.sensor_type)
    form.pin.data = sensor.pin
    form.limit_temp_up.data = sensor.limit_temp_up
    form.limit_temp_down.data = sensor.limit_temp_down
    form.limit_hum_up.data = sensor.limit_hum_up
    form.limit_hum_down.data = sensor.limit_hum_down
    form.limit_aqua_temp_up.data = sensor.limit_aqua_temp_up
    form.limit_aqua_temp_down.data = sensor.limit_aqua_temp_down

    if request.method == 'POST' and form.validate():
        name = form.name.data
        sensor_type = int(form.sensor_type.data)
        pin = form.pin.data
        limit_temp_up = form.limit_temp_up.data
        limit_temp_down = form.limit_temp_down.data
        limit_hum_up = form.limit_hum_up.data
        limit_hum_down = form.limit_hum_down.data
        limit_aqua_temp_up = form.limit_aqua_temp_up.data
        limit_aqua_temp_down = form.limit_aqua_temp_down.data

        db.session.commit()

        flash('You updated a sensor', 'success')

        return redirect(url_for('sensorlist_CRUD'))
    return render_template('sensorlist_edit.html', form=form)

使用以下代码生成模型类:

class Sensor(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    sensor_type = db.Column(db.Integer)
    pin = db.Column(db.Integer)
    limit_temp_up = db.Column(db.Float)
    limit_temp_down = db.Column(db.Float)
    limit_hum_up = db.Column(db.Float)
    limit_hum_down = db.Column(db.Float)
    limit_aqua_temp_up = db.Column(db.Float)
    limit_aqua_temp_down = db.Column(db.Float)

这里是 wtforms 的 Jinja 模板:

{% extends 'layout.html' %}

{% block body %}
  <h2><b>Edit Sensor</b></h2>
  {% from "includes/_formhelpers.html" import render_field %}
  <form method="POST" action="">
    <div class="form-group">
      {{render_field(form.name, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.sensor_type, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.pin, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_temp_up, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_temp_down, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_hum_up, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_hum_down, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_aqua_temp_up, class_="form-control")}}
    </div>
    <div class="form-group">
      {{render_field(form.limit_aqua_temp_down, class_="form-control")}}
    </div>
    <p><input type="submit" class="btn btn-primary" value="Submit"></p>
  </form>
{% endblock %}

我使用完全相同的表单、模型、python 代码和模板(以及其他 .html)来将数据添加到数据库中,并且效果很好。

我希望有人可以帮助我解决我所缺少的问题,或者可以给我一个简短描述我做错了什么的链接。我已经搜索了多个线程和其他帖子,但找不到解决方案。

提前感谢您提供的每一个帮助。

【问题讨论】:

    标签: python-2.7 flask sql-update flask-sqlalchemy wtforms


    【解决方案1】:

    你真的很接近,在POST 块下的代码中,你需要更新实际模型......现在你只是用表单数据设置了一堆变量,但它没有被应用到模型。像这样:

    @app.route('/sensorlist_edit/<string:id>', methods=['GET', 'POST'])
    @is_logged_in
    def sensorlist_edit(id):
        sensor = Sensor.query.filter_by(id=id).first()
        form = SensorListForm(request.form)
    
        if request.method == 'POST' and form.validate():
            sensor.name = form.name.data
            sensor.sensor_type = int(form.sensor_type.data)
            sensor.pin = form.pin.data
            sensor.limit_temp_up = form.limit_temp_up.data
            sensor.limit_temp_down = form.limit_temp_down.data
            sensor.limit_hum_up = form.limit_hum_up.data
            sensor.limit_hum_down = form.limit_hum_down.data
            sensor.limit_aqua_temp_up = form.limit_aqua_temp_up.data
            sensor.limit_aqua_temp_down = form.limit_aqua_temp_down.data
    
            db.session.commit()
    
            flash('You updated a sensor', 'success')
    
            return redirect(url_for('sensorlist_CRUD'))
    
        form.name.data = sensor.name
        form.sensor_type.data = str(sensor.sensor_type)
        form.pin.data = sensor.pin
        form.limit_temp_up.data = sensor.limit_temp_up
        form.limit_temp_down.data = sensor.limit_temp_down
        form.limit_hum_up.data = sensor.limit_hum_up
        form.limit_hum_down.data = sensor.limit_hum_down
        form.limit_aqua_temp_up.data = sensor.limit_aqua_temp_up
        form.limit_aqua_temp_down.data = sensor.limit_aqua_temp_down
    
        return render_template('sensorlist_edit.html', form=form)
    

    更新:

    我将表单分配移到 POST 部分下方,因为我认为它们正在用旧信息覆盖提交的表单数据...抱歉,我第一次错过了!!

    【讨论】:

    • 感谢您的回复。奇怪的是它没有效果......当我传递带有变量的闪存消息时,它仍然传递来自数据库的数据,而不是表单中的新类型数据?看起来表单,当填充来自数据库的数据时,在输入时不会在表单字段中添加新数据。
    • 您仍然缺少db.session.add(sensor)。另请注意,最好使用sensor = Sensor.query.get_or_404(id),因此如果用户将 url 中的 id 编辑为一些虚假数据,您的脚本不会出错。
    • 您不需要将现有对象添加回会话...如果您要向表中添加新记录,则只需使用db.session.add(...),如果您查询接收记录,就像 OP 所做的那样,这不是必需的
    • @Thijs 查看更新...我认为您正在用旧的数据库信息覆盖新发布的表单数据...试一试,我认为它会解决您的问题
    • @abigperson 救恩!!!谢谢,这是拼图的最后一块。它现在完美运行。感谢您的帮助和时间。并感谢大家分享他们的想法
    猜你喜欢
    • 2012-04-10
    • 2018-07-13
    • 2011-02-08
    • 2014-09-26
    • 2018-03-18
    • 2014-03-15
    • 2014-07-29
    • 2013-08-21
    • 1970-01-01
    相关资源
    最近更新 更多