Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

322
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda