63

当尝试使用 WTForms 设置 SelectField 的默认值时,我将值传递给 'default' 参数,如下所示。

class TestForm(Form):
  test_field = SelectField("Test: ", choices=[(1, "Abc"), (2, "Def")], default=2)

我也尝试过以下方法。

class TestForm(Form):
  test_field = SelectField("Test: ", choices=[(1, "Abc"), (2, "Def")], default=(2, "Def"))

既不将默认选定字段设置为“Def”。这适用于其他类型的字段,例如 TextField。如何设置 SelectField 的默认值?

4

8 回答 8

46

我相信这个问题是由Field' 的data属性default用 WTForms 不理解的东西覆盖的(例如,一个 DB 模型对象——它需要一个int)引起的。如果您像这样在构造函数中填充了表单,则会发生这种情况:

form = PostForm(obj=post)

data解决方案是在填充表单后手动设置属性:

form = PostForm(obj=post)
form.category.data = (post.category.id
                      if page.category
                      else 0) # I make 0 my default
于 2013-06-10T08:32:40.540 回答
39

您发布的第一种方式是正确的,它对我有用。它不起作用的唯一解释可能是您正在运行旧版本的 WTForms,它在 1.0.1 上对我有用

于 2012-08-23T21:25:59.297 回答
37

Flask-WTF 0.14.2用户在这里。因此,此答案适用于与我有类似问题的任何人。

基本上,以前的解决方案都不能与form.validate_on_submit().

设置form.test_field.data确实会在页面加载时更改默认值,但之后数据保持不变validate_on_submit(用户在浏览器中更改没有效果)。

设置form.test_field.defaultthen callform.process()也会在页面加载时更改值,但validate_on_submit会失败。

这是执行此操作的新方法:

class TestForm(Form):
    test_field = SelectField("Test", choices=[(0, "test0"), (1, "test1")])

@app.route("/test")
def view_function():
    form = TestForm(test_field=1)
    if form.validate_on_submit():
        ...
于 2017-04-07T14:10:27.930 回答
20

有几种方法可以做到这一点。您的第一个代码段确实是正确的。

如果您想在视图中动态执行此操作,您也可以执行以下操作:

form = TestForm()
form.test_field.default = some_default_id
form.process()
于 2015-02-24T00:52:52.650 回答
10

这是使用时的choices设置,它的工作原理如下:SelectFieldint

test_select = SelectField("Test", coerce=int, choices=[(0, "test0"), (1, "test1")], default=1)

或者:

class TestForm(Form):
    test_select = SelectField("Test", coerce=int)

@app.route("/test")
def view_function():
    form = TestForm()
    form.test_select.choices = [(0, "test0"), (1, "test1")]
    form.test_select.default = 1
    form.process()
于 2016-09-08T03:30:18.470 回答
3

如果您正在使用 flask_wtf 并希望为嵌套在 FieldList 中的不同 SelectFields 设置默认值,如下所示

from flask_wtf import FlaskForm


class FormWithSelect(FlaskForm):
    my_select_field = SelectField(validators=[DataRequired()], coerce=int)


class FormWithMultipleSelects(FlaskForm):
    select_fields = FieldList(FormField(FormWithSelect), min_entries=1)
    submit = SubmitField(label="save all the select field values")

解决方案是覆盖data,而不是default您期望的那样。

def generate_my_form(my_data, overwrite_data=True):
    form = FormWithMultipleSelects(select_fields=[{
        "my_select_field": {
             "name": d["name"],
             # ...
        }
    } for d in my_data]))
    for n range(len(form.select_fields)):
        form.select_fields[n].my_select_field.choices = [(1,'foo'), (2,'bar')]
        # I wan't 'bar' to be the option selected by default
        # form.select_fields[n].my_select_field.default = 2  # has no effect!
        if overwrite_data:
            form.select_fields[n].my_select_field.data = 2 #  works

基本上这个解决方案类似于上面的Elliots 回答;我只是想为更复杂的 FieldList 案例提供解决方案。nikitz在评论中提到,有一个副作用:form.validate_on_submit()如果你覆盖它就不起作用datadata您可以构建一个简单的解决方法,在其中禁用调用时的覆盖validate_on_submit()

 form_for_validation = generate_my_form(my_data, False)
 if form_for_validation.validate_on_submit():
      # do something with form_for_validation.data
 else:
     form_with_default_data = generate_my_form(my_data, True)
     render_template(..., form=form_with_default_data)

它不是超级优雅,但它确实有效。

PS:我的声誉太低,无法直接评论Elliot的正确答案。

于 2019-01-29T11:08:39.790 回答
0

我对动态设置默认选择字段有一些问题,我认为这很有用。模型是这样的:

class State(db.Model):
    __tablename__ = 'states'
    id = db.Column(db.Integer, primary_key=True)   
    name = db.Column(db.String(128), nullable=False)


class City(db.Model):
    __tablename__ = 'cities'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    state_id = db.Column(db.Integer, db.ForeignKey('states.id'))   
    state = db.relationship(State, backref='state')


class User(UserMixin, db.Model):
    ...
    city_id = db.Column(db.Integer, db.ForeignKey('cities.id'))
    city = db.relationship('City', backref='city')

表格是这样的:

class UserEditForm(FlaskForm):
    ...
    state = SelectField("state", coerce=int)
    city = SelectField("city", coerce=int)
    ....

  def __init__(self, state_id, *args, **kwargs):
       super(UserEditForm, self).__init__(*args, **kwargs)
       self.state.choices =  [(state.id, state.name)
                        for state in State.query.order_by('name').all()]
       self.city.choices = [(city.id, city.name)
                            for city in   City.query.filter_by(state_id=state_id).order_by('name').all()]   

视图是这样的:

@dashboard.route('/useredit', methods=['GET', 'POST'])
@login_required
def useredit():
    ....
    user = current_user._get_current_object()       
    form = OrganEditForm(state_id=user.city.state_id, state=user.city.state_id, city=user.city_id)
     ....

它运行良好并正确设置 Selectfield 默认值。但我改变了这样的代码:

鉴于:

@dashboard.route('/useredit', methods=['GET', 'POST'])
    @login_required
    def useredit():
        ....
        user = current_user._get_current_object()       
        form = OrganEditForm(obj=user)
         ....

在表格中

def __init__(self, *args, **kwargs):
       super(UserEditForm, self).__init__(*args, **kwargs)
       self.state.choices =  [(state.id, state.name)
                        for state in State.query.order_by('name').all()]
       self.city.choices = [(city.id, city.name)
                            for city in   City.query.filter_by(state_id=kwargs['obj'].city.state_id).order_by('name').all()] 

但是这次没有设置城市默认值。我改变了这样的形式:

def __init__(self, *args, **kwargs):
           kwargs['city'] = kwargs['obj'].city_id
           super(UserEditForm, self).__init__(*args, **kwargs)
           self.state.choices =  [(state.id, state.name)
                            for state in State.query.order_by('name').all()]
           self.city.choices = [(city.id, city.name)
                                for city in   City.query.filter_by(state_id=kwargs['obj'].city.state_id).order_by('name').all()] 

但它没有用。我尝试了很多解决方案,最后我将城市变量名称更改为 usercity:

usercity= SelectField("city", coerce=int)

kwargs['city'] = kwargs['obj'].city_idkwargs['usercity'] = kwargs['obj'].city_id。之后它工作正常。

问题是,当我设置时,城市选择字段的默认值从我在模型中定义的obj=user读取。kwargs['obj'].cityuser

于 2019-03-19T18:12:49.327 回答
0
Python Flask SelectField choices 

    # method 1 - routes.py
     form.proj_cat_id.default    = table1.proj_cat_id
     form.process()  # for preset 

    # method 2 - routes.py
    form.proj_cat_id.process_formdata([table1.proj_cat_id])



# method 3  - routes.py
      proj_cat_id_default    = table1.proj_cat_id
      return render_template('abc.html',proj_cat_id_default=proj_cat_id_default)

# method 3 - abc.html
        {% set z = form.proj_cat_id.process_data(proj_cat_id_default) %}
        {{ form.proj_cat_id(class="form-control form-control-lg") }}
于 2021-03-19T02:46:15.570 回答