склянка wtforms QuerySelectFeld form.populate_obj поля не заполнены и при заполнении ошибка переводится - PullRequest
0 голосов
/ 14 октября 2019

Я борюсь с двумя проблемами,

1 / QuerySelectField не заполнен

2 / Ошибка перевода, если поле заполнено

У меня есть функция добавления и редактированиеЯ использую функцию "из wtforms_alchemy.fields import QuerySelectField", чтобы в раскрывающемся списке был доступен выбор из одной модели базы данных. В функции «addboilercircuit» это работает, в форме отображается выпадающий список, и я могу отправить форму. в функции «editboilercircuit» я использую formpopulate_obj все поля заполнены, примите QuerySelectField , выпадающий список виден, но он не отображает сохраненный выбор, если я выберу одиниз вариантов и затем отправить я получаю сообщение об ошибке translate . Вот мой код:

form.py

def boiler_ID():
    return Boilers.query

class AddBoilerCircuitForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    boiler_ID = QuerySelectField('Boiler_ID',
                    query_factory=boiler_ID,
                    get_label='id')
    submit = SubmitField('Register')

models.py

class Boilers(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    state = db.Column(db.String(9))

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

class Boilercircuit(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    boiler_ID = db.Column(db.String(30))

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

boilers.py

@bp.route('/boilers/editboilercircuit/<int:id>', methods=('GET', 'POST')) 
@login_required
def editboilercircuit(id):
    obj = Boilercircuit.query.get(id) or Boilers()
    form = AddBoilerCircuitForm(request.form, obj=obj)
    if form.validate_on_submit():
        form.populate_obj(obj)
        db.session.add(obj)
        db.session.commit()
        flash('Congratulations, you are have updated a Boiler Circuit!')
        return redirect(url_for('boilers.boilercircuits'))
    return render_template('boilers/editboilercircuit.html', title= 'edit boilercircuit',
                          form=form, obj=obj)

и HTMLeditboilercircuit.html

  <h2>Edit Boiler Circuit</h2>
      <form action="" method="post">
      {{ form.hidden_tag() }}
          <div>{{ form.name.label }} {{ form.name(class="input") }}</div>
          <div>{{ form.boiler_ID.label }} {{ form.boiler_ID(class="input") }}</div>
          <div>{{ form.submit(class="submit") }}</div>
     <form>

сообщение об ошибке

AttributeError: у объекта 'Boilers' нет атрибута 'translate'

в "addboilercircuit""функция работает нормально, примите, на мой взгляд, функцию, я должен добавить str к каждому QuerySelectField, чтобы избежать" ошибки перевода ", вот мой код

def addboilercircuit():
    form = AddBoilerCircuitForm()
    if form.validate_on_submit():
        boilercircuit = Boilercircuit(name=form.name.data,
                boiler_ID=str(form.boiler_ID.data), #here I have added "str"

Я искал на всех форумах похожую проблему, нобольшинство из них относится к функции добавления, это помогло мне очистить мой код (спасибо @sean) и многие другие. Надеюсь, мой вопрос понятен Заранее спасибо

Пол

1 Ответ

1 голос
/ 15 октября 2019

Ключевым моментом здесь является то, что поля с поддержкой ORM фактически имеют дело с объектами ORM, а не со скалярными значениями для значений обработанных полей формы. Это подтверждается в вызываемом запросе, который вы передаете конструктору QuerySelectField:

def boiler_ID():
    return Boilers.query

Это запрос, который возвращает Boilers экземпляров, а не целочисленные значения идентификатора.

Чтобы отсортировать его, добавьте поле relationship в вашу модель с именем boiler и свяжите с ним поле формы. Нам также нужно добавить внешний ключ на boilercircuit.boiler_ID, чтобы связь могла установить путь соединения к таблице boilers.

# adds a `ForeignKey` constraint to `boiler_ID` and a `boiler` 
# relationship to your `BoilerCircuit` object.

class Boilercircuit(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    boiler_ID = db.Column(db.String(30), db.ForeignKey("boilers.id"))

    boiler = db.relationship("Boilers")

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

Затем измените форму:

# renames the `boiler_ID` field to `boiler` and also the field's label.
class AddBoilerCircuitForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    boiler = QuerySelectField('boiler',
                    query_factory=boiler_ID,
                    get_label='id')
    submit = SubmitField('Register')

Вам также нужно будет изменить любые ссылки, которые вы указали на AddBoilerCircuitForm.boiler_ID во всех ваших представлениях и шаблонах, так как это поле больше не существует в форме.

...