Flask – Prepopulate SelectMultipleField

When you’re reading on this articles, maybe you’re like me struggling in how to pre-populate the values from saved data.

Models:

class Category(db.Model):
    __tablename__ = 'category'
    id = db.Column(db.Integer, primary_key=True)
    name_en = db.Column(db.String(100), nullable=False, unique=True)

categories = db.Table(
    'categories',
    db.Column('merchant_id', db.Integer, db.ForeignKey('merchant.id')),
    db.Column('category_id', db.Integer, db.ForeignKey('category.id'))
)

class Merchant(db.Model):
    __tablename__ = 'merchant'
    id = db.Column(db.Integer, primary_key=True)
    merchant_code = db.Column(db.String(255), nullable=False)

    categories = db.relationship('Category', secondary=categories,
        backref=db.backref('categories', lazy='dynamic'))

 

Form

The import part here isĀ coerce=int, as in value is integer

class MultiCheckboxField(SelectMultipleField):
    widget = widgets.ListWidget(prefix_label=False)
    option_widget = widgets.CheckboxInput() 

class WorkTypeForm(FlaskForm):
    categories = SelectMultipleField('Select Category', 
        coerce=int,
        option_widget=widgets.CheckboxInput(), 
        widget=widgets.ListWidget(prefix_label=False) )
    
    submit = SubmitField('Update')    

 

View

The checkbox true value is integer (category id), therefore we need to provided the integer list.

@login_required
@merchant.route('/categories/<code>', methods = ['GET','POST'])
def worktype(code=None, error=None):
    categories = Category.query.all()
    
    form = WorkTypeForm()
    form.categories.choices = [(c.id, c.name_en) for c in categories ]
    
    merchant = Merchant.query.filter(Merchant.merchant_code == code).first()
    if merchant is None:
        return render_template('404.html'), 404
    
    if request.method == 'GET':
        if merchant.categories:
            # This is where you prepopulate 
            form.categories.data = [(c.id) for c in merchant.categories]

    if form.validate_on_submit():
        .....
       // code omitted
        .....
    return render_template('categories.html', form=form, error=error, code=code)

 

Html

<div class="table-responsive">
   {% if form %}
      {{ wtf.quick_form(form) }}
   {% endif %}
</div>

 

Flask – Prepopulate SelectMultipleField

One thought on “Flask – Prepopulate SelectMultipleField

  • March 7, 2021 at 8:42 am
    Permalink

    Thank you. This was very insightful to find a solution to my problem.

    My form affects multiple Models through relationships so I was using something along the lines of:

    queryA = session….
    queryB = session….

    form = myForm(obj=queryA, field_name_not_in_queryA=queryB.fieldName, fieldName_with_multiple_choices=?)

    All the fields in my form were being pre-populated except the one that required multiple choices.

    I just added this (coming from your example)

    queryC = session…

    form.field_name_with_multiple_choices.data = [(choice.name) for choice in queryC]

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.