wtf-forms populate.object AttributeError: объект «Heatingcircuit» не имеет атрибута «translate» при редактировании записи в БД - PullRequest
1 голос
/ 27 апреля 2019

Прежде всего я знаю, в чем проблема, но я не знаю, почему или как это исправить, я знаю, что функция должна передать строку в базу данных, у меня есть функция просмотра для создания и редактирования, вСоздание части Я добавил «str» в функцию, чтобы преодолеть проблему, но я не знаю, как это сделать для части редактирования.Форма имеет querySelectField, который правильно заполняется для части создания, и когда я отправляю "str", преобразовывает результат запроса правильно.

Итак, чтобы преодолеть проблему, я добавил «str» в часть create функции, но я не могу понять, как добавить это в часть редактирования с помощью «populate.obj», также я ожидаю, чтополе для заполнения данными, хранящимися в БД, когда я создал форму, но это не так.Только это поле QuerySelect вызывает проблемы.Вот часть моего кода.

@bp.route('/control/addheatingcircuit', methods=['GET', 'POST']) 
@bp.route('/control/addheatingcircuit/<int:id>', methods=('GET', 
'POST')) 
@login_required
def addheatingcircuit(id=None):
    if id is not None:
        obj = Heatingcircuit.query.get(id) or Heatingcircuit()
        form = AddHeatingcircuitForm(request.form, obj=obj)
        if form.validate_on_submit():
            form.populate_obj(obj)
            db.session.add(obj)
            db.session.commit()
            return redirect(url_for('index.index'))
    else:
        form = AddHeatingcircuitForm()
        if form.validate_on_submit():
            heatingcircuit = Heatingcircuit(name=form.name.data, 
sensor_ID1=str(form.sensor_ID1.data),\ #here i have added 'str'
                           pin_ID1=str(form.pin_ID1.data))
            db.session.add(heatingcircuit)
            db.session.commit()
            flash('Congratulations, you are now a registered a new 
device!')
            return redirect(url_for('index.index'))
    return render_template('control/addheatingcircuit.html', title= 
'add edit heating circuit',
                          form=form)

forms.py

from wtforms_alchemy.fields import QuerySelectField
class AddHeatingcircuitForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
sensor_ID1 = QuerySelectField('sensor_ID1', 
                query_factory=lambda: Sensors.query.all(),
                allow_blank=True, get_label='sensorID')
sensor_ID2 = QuerySelectField('sensor_ID2', 
                query_factory=lambda: Sensors.query.all(),
                allow_blank=True, get_label='sensorID')
.....

models.py

class Heatingcircuit(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    sensor_ID1 = db.Column(db.String(30))
    sensor_ID2 = db.Column(db.String(30))
    sensor_ID3 = db.Column(db.String(30))
    pin_ID1 = db.Column(db.Integer)
    pin_ID2 = db.Column(db.Integer)
    pin_ID3 = db.Column(db.Integer)
    temp = db.Column(db.Float)
    state = db.Column(db.String(9))
    timer = db.relationship('Timers', backref='time')

    def __repr__(self):
        return '{}'.format(self.id)

Я смотрел много вопросов на форумах, ноэто самое близкое совпадение Flask WTF 'StringField' объект не имеет атрибута 'translate'

Поэтому, как объяснено, я ожидаю, что функция редактирования существующей части записи заполнит форму информациейуже зарегистрирован, и что, когда я изменяю это и отправляю, заполненная форма исключается, вместо этого я получаю это сообщение об ошибке;

AttributeError: 'Heatingcircuit' object has no attribute 'translate'

(полный журнал ошибок возможен при необходимости)

большое спасибо Пол

РЕДАКТИРОВАТЬ, я смотрю на этот учебник https://www.rithmschool.com/courses/flask-fundamentals/forms-with-wtforms Здесь говорится о CSRF и о том, как отключить токены для итерации по форме. Может ли это быть моей проблемой?Эта проблема также влияет на SelectField.

Edit2 Я попробовал идею, упомянутую в ссылке http://wtforms.simplecodes.com/docs/0.6.1/ext.html#module-wtforms.ext.sqlalchemy.fields, в этом коде из-за ошибки "sqlalchemy.exc.InvalidRequestError: Entity" не имеет свойства "enabled" "Это мой код

def enabled_sensors():
    return Sensors.query.filter_by(enabled=True)

Но не удалось отредактировать ошибку

Traceback (most recent call last):
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
 File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/flask_login/utils.py", line 261, in decorated_view
return func(*args, **kwargs)
  File "/home/pi/heating/homeHeating/control/control.py", line 154, in addheatingcircuit
db.session.commit()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/scoping.py", line 162, in do
return getattr(self.registry(), name)(*args, **kwargs)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1026, in commit
self.transaction.commit()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 493, in commit
self._prepare_impl()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 472, in _prepare_impl
self.session.flush()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2451, in flush
self._flush(objects)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2589, in _flush
transaction.rollback(_capture_exception=True)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 129, in reraise
raise value
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2549, in _flush
flush_context.execute()
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
rec.execute(self)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 589, in execute
uow,
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 236, in save_obj
update,
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 978, in _emit_update_statements
statement, multiparams
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 988, in execute
return meth(self, multiparams, params)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement
distilled_params,
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1248, in _execute_context
e, statement, parameters, cursor, context
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1468, in _handle_dbapi_exception
util.reraise(*exc_info)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 129, in reraise
raise value
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1244, in _execute_context
cursor, statement, parameters, context
  File "/home/pi/heating/venv/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 552, in do_execute
cursor.execute(statement, parameters)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/cursors.py", line 168, in execute
query = self.mogrify(query, args)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/cursors.py", line 147, in mogrify
query = query % self._escape_args(args, conn)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/cursors.py", line 127, in _escape_args
return {key: conn.literal(val) for (key, val) in args.items()}
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/cursors.py", line 127, in <dictcomp>
return {key: conn.literal(val) for (key, val) in args.items()}
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/connections.py", line 467, in literal
return self.escape(obj, self.encoders)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/connections.py", line 460, in escape
return converters.escape_item(obj, self.charset, mapping=mapping)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/converters.py", line 27, in escape_item
val = encoder(val, mapping)
 File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/converters.py", line 118, in escape_unicode
return u"'%s'" % _escape_unicode(value)
  File "/home/pi/heating/venv/lib/python3.7/site-packages/pymysql/converters.py", line 73, in _escape_unicode
    return value.translate(_escape_table)
AttributeError: 'Sensors' object has no attribute 'translate'

У меня было то же самое сообщение об ошибке для второй половины функции "def addpin ():", яперезапустил и обнаружил, что мне нужно вернуть строку, поэтому я добавил str(form.sensor_ID1.data) "str", и это решило проблему там. Но первая половина функции - это часть редактирования, и у меня теперь есть проблема, но я не знаю, как ее решитьЭто.ошибка здесь, я верю;

    if id is not None:
        obj = Heatingcircuit.query.get(id) or Heatingcircuit()
        form = AddHeatingcircuitForm(request.form, obj=obj)
        if form.validate_on_submit():
            form.populate_obj(obj)
            db.session.add(obj)
            db.session.commit()

Спасибо за помощь. С уважением, Павел

1 Ответ

0 голосов
/ 27 апреля 2019

Две проблемы.Во-первых, аргумент QuerySelectField * query_factory принимает запрос, а не список результатов.Так что снимите .all():

sensor_ID1 = QuerySelectField('sensor_ID1', 
                query_factory=lambda: Sensors.query,
                allow_blank=True, get_label='sensorID')

Во-вторых, data для данного поля формы даст вам объект Sensors.Так что вы не можете просто разыграть его, вам нужно попросить его за id.То же самое касается поля pin_ID1.Как вы это сделаете, будет зависеть от того, как объявлен класс Sensors:

heatingcircuit = Heatingcircuit(
    name=form.name.data,
    sensor_ID1=form.sensor_ID1.data.sensorID,
    pin_ID1=form.pin_ID1.data.pinID
)
...