使用SQL查询填充WTForms SelectField

5

我想用这个查询返回的行填充WTForms SelectField:

cur.execute("SELECT length FROM skipakke_alpin_ski WHERE stock > 0")

这个查询返回不同类型滑雪板的滑雪长度行。cur.fetchall() 返回以下元组:

[(70,), (75,), (82,), (88,), (105,), (115,), (125,), (132,), (140,), (150,), (160,), (170,)]

我该如何将这些数字添加到一个SelectField中,使得每个滑雪板长度都可以成为可选择的选项?如果我要手动完成这个过程,我会按照以下步骤进行:

ski_size = SelectField('Ski size', choices=['70', '70', '75', '75'])

对于所有不同长度的情况,都要这样做。

4个回答

6
在我的一个项目中,我使用了以下代码:

模型

class PropertyType(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    title = db.Column(db.String(255), nullable=False)

    def __repr__(self):
        return str(self.id)

而在表单中。
from wtforms.ext.sqlalchemy.fields import QuerySelectField

class PropertyEditor(Form):
    property_type = QuerySelectField(
        'Property Type',
        query_factory=lambda: models.PropertyType.query,
        allow_blank=False
    )
    //Other remaining fields

希望这可以帮到您。

3

解决方案可能如下代码所示。

假设您有两个文件:routes.pyviews.py

routes.py文件中,您可以放置以下内容:

from flask_wtf import FlaskForm
from wtforms import SelectField

# Here we have class to render ski
class SkiForm(FlaskForm):
    ski = SelectField('Ski size')

views.py 文件中,您需要添加以下内容。
# Import your SkiForm class from `routes.py` file
from routes import SkiForm

# Here you define `cur`
cur = ...

# Now let's define a method to return rendered page with SkiForm
def show_ski_to_user():
    # List of skies
    cur.execute("SELECT length FROM skipakke_alpin_ski WHERE stock > 0")
    skies = cur.fetchall()

    # create form instance
    form = SkiForm()
    # Now add ski length to the options of select field
    # it must be list with options with (key, value) data
    form.ski.choices = [(ski, ski) for ski in skies]
    # If you want to use id or other data as `key` you can change it in list generator
    if form.validate():
        # your code goes here

    return render_template('any_file.html', form=form)

请记住,默认情况下 key 的值是unicode类型。如果您想使用int或其他数据类型,请在SkiForm类中使用 coerce 参数,像这样:

class SkiForm(FlaskForm):
    ski = SelectField('Ski size', coerce=int)

非常好的答案。它帮助我解决了我在表单验证中遇到的问题。恭喜你对概念的出色理解。关于“UNICODE”的评论是关键。非常感谢! - Ramiro

1

解决方案:

我遇到了类似的问题,以下是我的解决方法

class SkiForm(FlaskForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        cur.execute("SELECT length FROM skipakke_alpin_ski WHERE stock > 0")
        skies = cur.fetchall()

        self.ski_size.choices = [
            (ski , ski) for ski in skies
        ]

    ski_size = SelectField("Ski size")

解释:

我们修改了原始的FlaskForm,使得每次创建表单时都会执行数据库查询。

因此,SkiForm字段数据选项始终保持最新状态。


0
我通过以下方式解决了这个问题:
def fetch_available_items(table_name, column):
    with sqlite3.connect('database.db') as con:
        cur = con.cursor()
        cur.execute("SELECT length FROM skipakke_alpin_ski WHERE stock > 0")
        return cur.fetchall()

class SkipakkeForm(Form):
    alpin_ski = SelectField('Select your ski size', choices=[])

@app.route('/skipakke')
def skipakke():
    form = SkipakkeForm

    # Clear the SelectField on page load
    form.alpin_ski.choices = []        

    for row in fetch_available_items('skipakke_alpin_ski', 'length'):
        stock = str(row[0])
        form.alpin_ski.choices += [(stock, stock + ' cm')]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接