Search code examples
pythonflaskwtformsflask-wtforms

How can I create repetitive form elements in a DRY way with Flask-WTForms?


I have a WTForms form where I want the user to be able to upload up to 10 images, and also give the images captions and credits. Currently I declare all 10 sets of fields, but this seems redundant. Is there a way to create form fields with dynamic names, so I could create them in a loop?

class MyForm(Form):
    image1 = FileField('Upload')
    image1_caption = StringField('Caption')
    image1_credit = StringField('Credit')
    image2 = FileField('Upload')
    image2_caption = StringField('Caption')
    image2_credit = StringField('Credit')
    # ...through 10 images...

Solution

  • You can get what you're looking for by combining FormField with FieldList:

    class ImageForm(Form):
        image = FileField('Upload')
        caption = StringField('Caption')
        credit = StringField('Credit')
    
    class MyForm(Form):
        images = FieldList(FormField(ImageForm), min_entries=10)
    

    You can then access the individual ImageForm instances either through my_form_instance.images.entries or by iterating over my_form_instance.images:

    for image in my_form_instance.images:
        print(image.data['caption'], image.data['credit'])