簡體   English   中英

在 Flask / WTForms 中填充 select 字段更新上的文本字段

[英]Populate text fields on select field update in Flask / WTForms

伙計們,對此我感到頭疼, 這里有一種答案,但難以實施。

我目前有一個配方和 styles 表,當提交“添加配方”表單時,它會將 styles 表中的數據復制到配方中。 我想做的是添加配方表單中的 select 樣式,並讓這些數據填充表單字段。 因此,我希望例如在更新樣式 select 下拉列表時填充樣式類型。

我的設置:

路線:

@app.route('/recipe/new', methods=['GET', 'POST'])
@login_required
def addrecipe():
    form = RecipeForm()
    if form.validate_on_submit():
        recipe = Recipe(recipe_name=form.recipe_name.data, 
                        recipe_style=form.style.data.id,
                        style_name=form.style.data.name, 
                        style_type = form.style.data.type)
        db.session.add(recipe)
        db.session.commit()
        flash('You added your recipe, get brewing!', 'success')
        return redirect(url_for('recipes'))
    return render_template('add_recipe.html', title = 'Add Recipe', form=form, legend='Add Recipe')

楷模:

class Recipe(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    recipe_name = db.Column(db.String(100), nullable=False)
    recipe_style = db.Column(db.Text, db.ForeignKey('styles.id'))
    style_name = db.Column(db.String(100))
    style_type = db.Column(db.String(100))


# used for query_factory    
def getStyles():
    return Styles.query.order_by(Styles.name.asc())

Forms:

class RecipeForm(FlaskForm):
    recipe_name = StringField('Recipe Name', validators=[DataRequired(), Length(min=2, max=20)])
    style = QuerySelectField(query_factory=getStyles, 
                            get_label="name")
    style_type = StringField('Style Type')

表格 HTML:

        <form method="POST" action="">
            {{ form.hidden_tag() }}
            <legend class="border-bottom mb-4">{{ legend }}</legend>
                <fieldset class="form-group card p-3 bg-light">
                    <h5 class="card-title">Overview</h5>
                    <div class="form-row">
                    <div class="form-group col-md-3">
                        {{ form.recipe_name.label(class="form-control-label") }}
                        {% if form.recipe_name.errors %}
                            {{ form.recipe_name(class="form-control form-control-sm is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in form.recipe_name.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ form.recipe_name(class="form-control form-control-sm") }}
                        {% endif %}
                    </div>
            </fieldset>
            <fieldset class="form-group card p-3 bg-light">
                <h5 class="card-title">Style</h5>
                <div class="form-row">
                    <div class="form-group col-md-3">
                        {{ form.style.label(class="form-control-label") }}
                        <input class="form-control form-control-sm" type="text" placeholder="Search Styles" id="myInput" onkeyup="filterFunction()">
                        {% if form.style.errors %}
                            {{ form.style(class="form-control form-control-sm is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in form.style.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ form.style(class="form-control form-control-sm", id="style_name") }}
                        {% endif %}
                    </div>
                    <div class="form-group col-md-2">
                        {{ form.style_type.label(class="form-control-label") }}
                        {% if form.style_type.errors %}
                            {{ form.style_type(class="form-control form-control-sm is-invalid") }}
                            <div class="invalid-feedback">
                                {% for error in form.style_type.errors %}
                                    <span>{{ error }}</span>
                                {% endfor %}
                            </div>
                        {% else %}
                            {{ form.style_type(class="form-control form-control-sm", id="styletype", style_type_tag='{{ form.style.data.type }}' ) }}
                        {% endif %}
                    </div>
            </div>
            </fieldset>

到目前為止,我的 Javascript:

style_name.oninput = function(o) {
    // style = document.getElementById('styletype')
    styletype.value = $(o).attr('style_type_tag')
    }

我可以使用 JS function 獲得一些基本的東西。 所以當我更新下拉列表時,它會用一些文本填充該字段。 我想不通的是如何從數據庫中提取 style_type 信息。 此處頂部的鏈接將該信息加載到文本框的 html 標記中,但這與我所做的有點不同。 海報循環了一些項目,它不是一種形式。 我的style_type_tag只是顯示為原始文本。 我猜這里的循環很關鍵,但我還不能完全進入我的設置。

非常感謝任何幫助!

所以這個問題的答案是構建一個簡單的 API。 我確信有更簡單的方法,但我想在這里進行一些練習,並認為這對於在項目中構建其他功能很有用。

我關注了 Brad Traversy 的關於該主題的視頻,並使用 GET 部分進行了此操作。 他的項目是一個簡單的單文件項目,所以我不得不在我的項目中更多地參與導入等。

  1. 抓住postman與 API 交互
  2. 安裝 Marshmallow ,到requirements.txt ,添加以下行:
flask-marshmallow
marshmallow-sqlalchemy

然后運行pip install -r requirements.txt

  1. 導入並初始化棉花糖。 在 init.py 中:
from flask_marshmallow import Marshmallow
ma = Marshmallow(app)
  1. 將樣式模式添加models.py
# import module
from flaskblog import ma

# create schema with the fields required
class StyleSchema(ma.Schema):
    class Meta:
        fields = ("id", "name", "origin", "type")

# initialise single style schema
style_schema = StyleSchema()
# initialise multiple style schema
styles_schema = StyleSchema(many=True)

請注意,對於 Marshmallow,不再需要strict=True

  1. 創建 endpoints/routes ,到routes.py
# Get All Styles

@app.route('/styleget', methods=['GET'])
def styles_get():
    all_styles = Styles.query.all()
    result = styles_schema.dump(all_styles)
    # return jsonify(result.data) - note that this line is different to the video, was mentioned in the comments. Was originally "return jsonify(result.data)"
    return styles_schema.jsonify(all_styles)

# Get Single Product

# passes the id into the URL
@app.route('/styleget/<id>', methods=['GET'])
def style_get(id):
    style = Styles.query.get(id)
    return style_schema.jsonify(style)
  1. 更新 JS 腳本
style_name.onchange = function() {
        // creates a variable from the dropdown
    style = document.getElementById('style_name').value
        // uses the variable to call the API and populate the other form fields
    fetch('/styleget/' + style).then(function(response) {
      response.json().then(function(data) {
        // this takes the 'type' data from the JSON and adds it to the styleType variable
        styleType = data.type;
        // adds the data from the variable to the form field using the ID of the form. 
        styletype.value = styleType
      });
    });
}

希望這可以幫助遇到同樣挑戰的任何人!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM