【问题标题】:WTForm - QuerySelectField doesn't take the given/default value from database. Flask - WTForms - SqlalchemyWTForm - QuerySelectField 不从数据库中获取给定/默认值。 Flask - WTForms - Sqlalchemy
【发布时间】:2020-02-21 12:13:37
【问题描述】:

我使用 wtform 来添加和编辑对象,我使用 queryselectfield 作为外键。 queryselectfield 总是取行中的第一个值。据我所知,正确的值实际上是正确传递的,只是由于某种原因它不接受它。

型号例如:

class State(db.Model):
    __tablename__ = 'state'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    country_id = db.Column(db.Integer, db.ForeignKey('country.id'))
    name = db.Column(db.String(150))
    factor = db.Column(db.Float)
    time_created = db.Column(DateTime(timezone=True),
                             server_default=func.now())
    time_updated = db.Column(DateTime(timezone=True), onupdate=func.now())

    def __init__(self, country_id, name, factor):
        self.country_id = country_id
        self.name = name
        self.factor = factor

    def __repr__(self):
        return '{} - {}'.format(self.country_id, self.name)

示范国家

class Country(db.Model):
    __tablename__ = 'country'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(150))
    shortcut = db.Column(db.String(3))
    states = db.relationship('State', backref='country', lazy=True)
    time_created = db.Column(DateTime(timezone=True),
                             server_default=func.now())
    time_updated = db.Column(DateTime(timezone=True), onupdate=func.now())

    def __init__(self, name, shortcut):
        self.name = name
        self.shortcut = shortcut

    def __repr__(self):
        return '{} - {} - {}'.format(self.id, self.name, self.shortcut)

查看:

@admin_blueprint.route('/admin/state/edit/<int:state_id>',
                       methods=['GET', 'POST'])
@login_required
def edit_state(state_id):
    """Edit state"""
    obj = State.query.filter_by(id=state_id).first_or_404()
    form = StateForm(obj=obj)
    if request.method == 'POST' and form.validate_on_submit:
        obj.country_id = form.country_id.data.id
        obj.name = form.name.data
        obj.factor = form.factor.data
        db.session.commit()
        log_entry_edit(State, obj)
        return redirect(url_for('admin.list_states'))
    return render_template('admin/state_form.html', form=form,
                           title='Edit State')

表格:

def countries():
    return Country.query

class StateForm(FlaskForm):
    name = StringField('State Name')
    factor = FloatField('Factor')
    country_id = QuerySelectField('Country', query_factory=countries)
    submit = SubmitField('Save')

模板:

    <div>
         {{ form.country_id.label }} 
         {{ form.country_id(class="form-control form-group") }}
         <output style="color: red;"  for="country_id" id="selected-country_id">
              ACTUAL ID: {{ form.country_id.data }}
         </output>
    </div>
    {% if form.country_id.errors %}
        <ul class="errors">
            {% for error in country_id.errors %}
                <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}

如下图所示,表单采用第一个值,如果我不再次选择我想要的值,它也会覆盖数据库。 实际正确的值到达表单虽然(红色的 ID):

screenshot of template output

我刚开始使用烧瓶、wtforms 等,老实说,我看不出我做错了什么。有人知道吗?

【问题讨论】:

  • 请同时提供“Country”模型类。
  • 好的,我在问题中添加了它

标签: python flask flask-sqlalchemy flask-wtforms


【解决方案1】:

我也遇到过类似的问题,终于弄明白了:在表单中调用('GET')时,你必须单独获取外键的数据,然后再用'POST'设置:

if request.method == 'GET':
    form.country_id.data = obj.country_id
if request.method == 'POST' and form.validate_on_submit:
    # as before 

【讨论】:

    猜你喜欢
    • 2014-03-02
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多