Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

311
Vistas
Flask-WTF form with a variable number of fields (a list of items)

I've a form to create a cocktail recipe. It has some common fields like name, description and other, and also a list of ingredients. An ingredient has an ID (foreign-key for a table of ingredients), as the value of a select tag, a name and a quantity numeric field, as user input. At first, in the HTML there is only one field for an ingredient; if the user want to add another ingredient to the recipe, a button 'Add ingredient' create another field, just after the previous one.

How can I manage this kind of form with WTForms and Flask-WTF, in a Python/Flask backend? My problem is: how can I say in the form class "there is this list that must have at least one item (an ingredient), and no maximum" so that I can properly insert the recipe into database?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

maybe create a 3rd table?

Table 1 (Cocktail Table):
cocktail_id
cocktail_name

Table 2 (Ingredients Table):
cocktail_id
ingredients_name

Table 3 (Cocktail Ingredients Table):
cocktail_ingredients_id
cocktail_id
ingredients_id
quantity

Then for a given cocktail, search table 3 for all results of cocktail_id.
You can inner join the other tables to get the ingredient name or cocktail name when needed.

When uploading to database, you would just need to create a new entry for each cocktail ingredient you're saving to the cocktail ingredients table; with the cocktail_id, ingredients_id, and the quantity.

EDIT 1: There are many things you could do, for example when you are creating your form in your route, you could send to it your cocktail_id, and then when you're creating your form, you'll search for all instances of cocktail_id in your Table 3; and create a new (or set of) field(s) for each result. And the moment the user pressing 'add ingredient', you could send them

def createForm(cocktail_id):
    
    class FormClass(FlaskForm):
        # put your non dynamic fields here
        pass
    # add in your fields that are dependent on how many ingredients 

    post_variables_list = []

    # find all table 3 results for given cocktail
    table3_objects = Table3.query.filter_by(id=cocktail_id).all()
    for table3_object in table3_objects:
        setattr(FormClass, f'ingredientname_{table3_object.table3_id}', StringField('Ingredient Name', default=table3_object.ingredient_name))

        post_variables_list.append(f'ingredientname_{table3_object.table3_id}')

    return FormClass(), post_variables_list


@app.route('/example_route/<int:cocktail_id>')
def example_route(cocktail_id):

     form, post_variables_list = createForm(cocktail_id)
     if request.method=='POST':
        submit_dictionary = {}
        submit_dictionary = form.data

        for current_variable in post_variables_list:
            fieldname, table3_id = current_variable.split('_')
        
            # find existing object, that you can create by redirecting to a different route 
            # which just creates a new table 3 entry, which is associated w/ this cocktail each time you
            # press add ingredient and then redirects you to here
            table3_object = db.session.query(Table3).filter(Table3.id==table3_id).first()
            if fieldname = 'name':
                table3_object.name = submit_dictionary[current_variable]
            # could have other conditions here for other fields

            db.session.add(table3_object)
            db.session.commit()
            

# route which just creates a new empty ingredient
@app.route('create_new_empty_ingredient/int:cocktail_id')
def create_new_empty_ingredient(cocktail_id):

    # create new entry in table 3
    table3_object = Table3 (
        cocktail_id = cocktail_id
    )
    db.session.add(table3_object)
    db.session.commit()

    # redirect back to example_route
    return redirect(url_for('example_route', cocktail_id=cocktail_id))
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda