【问题标题】:wtforms Dynamic Select Field popluate default value from saved object datawtforms Dynamic Select Field 从保存的对象数据中填充默认值
【发布时间】:2025-12-03 19:00:01
【问题描述】:

我正在尝试使用具有选择字段的表单更新对象。 选择字段的选择在路线中决定。这使得新的选择会覆盖保存的数据。

我想填充选择字段,然后将默认的第一选择设为用户选择。

这是我目前的代码。

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

此代码生成状态列表。不是之前保存为选定选项的值用户的状态列表。

【问题讨论】:

    标签: python flask wtforms flask-wtforms


    【解决方案1】:

    您可以参考此thread 以获得答案。

    对于你的情况,有两种方法

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

    或者

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

    任何一种方式都有效。

    【讨论】:

      【解决方案2】:

      如果要在渲染表单时设置默认的selected选项,需要设置data属性:

      form.state.data = state_id

      【讨论】:

        【解决方案3】:

        首先将对象“文章”数据添加到这样的参数中:

        @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,
            )
        

        我们的表单“ArticleForm”用于添加或更新文章,如下所示:

        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"})
        

        最后在我们的模板中创建条件“如果对象存在”,如下所示:

        <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>
        

        我们将选择部分更改为:

        <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>
        

        最后别忘了在 add_article 视图的参数中添加“article=None”,例如:

        @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,
            )
        

        【讨论】: