1

I am trying to update an object with a form that has a select field. The select field choices are decided in the route. That makes it so the new choices overwrites the saved data.

I want to populate the select field and then make default first choice the one user selected.

Here is the code I have so far.

def approve_seller(seller_id):
    obj_to_edit = model.query.get(seller_id)
    form = AForm(request.form,obj=obj_to_edit)
    choices = [("", "---")]
    for s in State.query.all():
        choices.append((str(s.id), s.name))
    form.state.choices = choices

this code results in a list of states. Not the list of states with the value user saved previously as the selected option.

ichbinblau
  • 4,507
  • 5
  • 23
  • 36
Holly Johnson
  • 509
  • 1
  • 13
  • 25

3 Answers3

4

You may refer to this thread for answers.

For your case, there are two ways

form.state.default = <state_id> # eg.'CA'
form.process()

Or

form.state.data = <state_id> # eg. 'FL'

Either way works.

Community
  • 1
  • 1
ichbinblau
  • 4,507
  • 5
  • 23
  • 36
1

If you want to set the default selected option when rendering the form, you need to set the data attribute:

form.state.data = state_id

Matt Healy
  • 18,033
  • 4
  • 56
  • 56
0

first add object "article" data to parameters like this:

@app.route('/update_article/<id>', methods=['GET', 'POST'])
@login_required
def update_article(id):
    categorias = Category.query.all()
    titulo = trad_art["Edit Article"]["es"]

    article = Article.query.get(id)

    form = ArticleForm(obj=article)
    if form.validate_on_submit():
        form.populate_obj(article)
        db.session.commit()
        return redirect(url_for('update_images', id=id)) # or your favorite redirect

    return render_template(
        "add_article.html",
        article=article,
        form=form,
        titulo=titulo,
        categorias=categorias,
    )

our form "ArticleForm" is used for adding or update Article like this:

class ArticleForm(FlaskForm):
    name = StringField(trad_art['name']["es"], render_kw={"placeholder": "Nombre del producto"}, validators=[
                       DataRequired(), Length(max=64)])
    category = StringField(trad_art['Category']["es"], validators=[
                           DataRequired(), Length(max=64)])
    quantity = IntegerField(trad_art['Quantity']["es"])
    description = TextAreaField(trad_art['Description']["es"], render_kw={"rows": 10, "cols": 30}, validators=[
        DataRequired()])
    is_vintage = BooleanField(trad_art['Is Vintage']["es"])
    is_antic = BooleanField(trad_art['Is Antic']["es"])
    as_new = BooleanField(trad_art['As New']["es"])
    submit = SubmitField(trad_art['Save Article']["es"], render_kw={
                         "class": "btn btn-primary"})

And finally in our template make condition "if object exist" like this:

<form action="" method="post" novalidate>
                    {{ form.hidden_tag() }}
                    <div class="form-group">
                        {{ form.name.label }}<br>
                        {{ form.name }}<br>
                        {% for error in form.name.errors %}
                        <span style="color: red;">{{ error }}</span>
                        {% endfor %}
                    </div>
                    <div class="form-group">
                        {{ form.category.label }}<br>
                        <select id="get_category"  
                        value =""
                        name="category" class="form-control" >
                            <option value="Todos">Todos</option>
                            {% for categoria in categorias %}
                                <option 
                                value="{{ categoria.name }}"
                                {% if article.category == categoria.name %}selected{% endif %}
                                >{{ categoria.name }}</option>
                            {% endfor %}
                        </select>
                        <br>
                        {% for error in form.category.errors %}
                        <span style="color: red;">{{ error }}</span>
                        {% endfor %} 
                    </div>
                    <div class="form-group">
                        {{ form.quantity.label }}<br>
                        {{ form.quantity }}<br>
                        {% for error in form.quantity.errors %}
                        <span style="color: red;">{{ error }}</span>
                        {% endfor %}
                    </div>
                    <div class="form-group">
                        {{ form.description.label }}<br>
                        {{ form.description }}<br>
                        {% for error in form.description.errors %}
                        <span style="color: red;">{{ error }}</span>
                        {% endfor %}
                    </div>
                    <div class="form-group">
                        {{ form.is_vintage() }} 
                        {{ form.is_vintage.label }}            
                    </div>
                    <div class="form-group">
                        {{ form.is_antic() }} 
                        {{ form.is_antic.label }}            
                    </div>
                    <div class="form-group">
                        {{ form.as_new() }} 
                        {{ form.as_new.label }}            
                    </div>
                    <div class="form-group">
                        {{ form.submit() }}
                    </div>
                </form>

We change our select section to:

<div class="form-group">
                        {{ form.category.label }}<br>
                        <select id="get_category"  
                        value =""
                        name="category" class="form-control" >
                            <option value="Todos">Todos</option>
                            {% for categoria in categorias %}
                                <option 
                                value="{{ categoria.name }}"
                                {% if article.category == categoria.name %}selected{% endif %}
                                >{{ categoria.name }}</option>
                            {% endfor %}
                        </select>
                        <br>
                        {% for error in form.category.errors %}
                        <span style="color: red;">{{ error }}</span>
                        {% endfor %} 
                    </div>

And finally not forgot to add "article=None" in parameters of add_article view like :

@app.route('/add_article', methods=['GET', 'POST'])
@login_required
def add_article():
    categorias = Category.query.all()
    titulo = trad_art["Edit Article"]["es"]

    form = ArticleForm()
    if form.validate_on_submit():
        name = form.name.data
        category = form.category.data
        quantity = form.quantity.data
        description = form.description.data
        is_vintage = form.is_vintage.data
        is_antic = form.is_antic.data
        as_new = form.as_new.data
        date_register = datetime.datetime.now()
        galery = '[]'

        article = User.query.filter_by(name=name).first()
        if article:  # if a article is found, we want to redirect back to signup page so user can try again
            # print('Article name already exists')
            msg01 = trad_art["Article already exists"]["es"]
            flash(msg01)
            return redirect(url_for('add_article'))
        # Creamos el articulo y lo guardamos
        # create a new article with the form data. and save it...
        new_article = Article(
            name=name,
            category=category,
            quantity=int(quantity),
            description=description,
            is_vintage=is_vintage,
            is_antic=is_antic,
            as_new=as_new,
            date_register=date_register,
            galery=galery)

        # add the new user to the database
        db.session.add(new_article)
        db.session.commit()
        return redirect(url_for('update_images', id=new_article.id))

    return render_template(
        "add_article.html",
        article=None,
        form=form,
        titulo=titulo,
        categorias=categorias,
    )
Fethi Pounct
  • 1,059
  • 5
  • 6