How do you set a default value for a WTForms SelectField?

后端 未结 7 612
-上瘾入骨i
-上瘾入骨i 2020-11-29 04:09

When attempting to set the default value of a SelectField with WTForms, I pass in value to the \'default\' parameter like so.

class TestForm(Form):
  test_fi         


        
相关标签:
7条回答
  • 2020-11-29 04:48

    There are a few ways to do this. Your first code snippet is indeed correct.

    If you want to do this in a View dynamically though, you can also do:

    form = TestForm()
    form.test_field.default = some_default_id
    form.process()
    
    0 讨论(0)
  • 2020-11-29 04:48

    This is a choices settings with SelectField when you use an int, it works like this:

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

    or:

    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()
    
    0 讨论(0)
  • 2020-11-29 04:50

    The first way you posted is correct, and it works for me. The only explanation for it not working can be that you are running an older version of WTForms, it worked for me on 1.0.1

    0 讨论(0)
  • 2020-11-29 04:52

    I believe this problem is caused by the Field's data attribute overriding the default with something that WTForms doesn't understand (e.g. a DB model object -- it expects an int). This would happen if you have populated your form in the constructor like so:

    form = PostForm(obj=post)
    

    the solution is to manually set the data attribute after the form has been populated:

    form = PostForm(obj=post)
    form.category.data = (post.category.id
                          if page.category
                          else 0) # I make 0 my default
    
    0 讨论(0)
  • 2020-11-29 04:55

    I have some problem with dynamic set default selectfield thati think can be useful. the model was like this:

    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')
    

    the form was like this:

    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()]   
    

    and the view was like this:

    @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)
         ....
    

    it works good and set Selectfield default value correctly. but i changed the code like this:

    in view:

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

    in forms

    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()] 
    

    but this time the city default value doesn't set. i changed form like this:

    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()] 
    

    but it didn't work. I tried many solution and in the last I changed the city variable name to usercity:

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

    and kwargs['city'] = kwargs['obj'].city_id to kwargs['usercity'] = kwargs['obj'].city_id. affter that it worked correctly.

    the problem was that when I set obj=user, default value for city selectfield read from kwargs['obj'].city that I defined in user model.

    0 讨论(0)
  • 2020-11-29 05:03

    Flask-WTF 0.14.2 user here. So this answer is for anyone who have similar problem with me.

    Basically, none of the previous solutions function properly with form.validate_on_submit().

    Setting form.test_field.data will indeed change the default value when the page is loaded, but the data stays the same after validate_on_submit (user changes in browser has no effect).

    Setting form.test_field.default then call form.process() also changes the value when the page is loaded, but validate_on_submit will fail.

    Here is the new way to do it:

    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():
            ...
    
    0 讨论(0)
提交回复
热议问题