Привет всем,
У меня проблема с редактированием данных с помощью wtforms, SQLAlchemy и SQlite3. Я создал форму и могу запрашивать данные, отфильтрованные по идентификатору. Форма отлично заполнена соответствующими данными. Но когда я изменяю данные и нажимаю «Отправить», данные не обновляются. На самом деле есть две проблемы. Во-первых, формы не передают новые типизированные данные обратно в 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)
А вот шаблон Jinja из wtforms:
{% 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) для добавления данных в базу данных, и это отлично работает.
Я надеюсь, что кто-то может помочь мне с тем, что мне не хватает, или может дать мне ссылку с кратким описанием того, что я делаю не так. Я уже просмотрел несколько тем и других сообщений, но не нашел решения.
Заранее благодарим за любую помощь, которую вы оказываете.





Вы действительно близки, в вашем коде под блоком 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-адресе на какие-то поддельные данные, вы не получите ошибку в своем скрипте.
вам не нужно добавлять существующий объект обратно в сеанс ... вам нужно использовать db.session.add(...) только в том случае, если вы добавляете новую запись в таблицу, если вы запрашиваете получение записи, как это делает OP, это не нужный
@Thijs видят обновления ... Я думаю, вы перезаписывали новые опубликованные данные формы с помощью старой информации о базе данных ... попробуйте, и я думаю, что это решит вашу проблему
@abigperson Спасение !!! Спасибо, это был последний кусок головоломки. Теперь он работает отлично. Спасибо за помощь и время. И спасибо всем за то, что поделились своими мыслями
Спасибо за ответ. Как ни странно, это не имеет никакого эффекта ... Когда я передаю флэш-сообщение с переменной в нем, оно по-прежнему передает данные из базы данных, а не новые типизированные данные в форме? Похоже, что форма при заполнении данными из базы данных не исключает новых данных в полях формы при вводе.