Python wtforms QuerySelectField:返回主键项以外的内容

Python wtforms QuerySelectField:返回主键项以外的内容,python,flask-wtforms,Python,Flask Wtforms,我正在使用Flask制作一个web应用程序 简而言之:当我们提交一个使用QuerySelectField+sqlalchemy query填充选择框的表单时,提交的实际值似乎是主键,但是如果我需要提交另一个值怎么办?假设一个表有两列,ID和Item,现在ID是主键,但是用户选择行不是按主键ID而是按项,这是他们看到的项名称,而不是主键ID。但是表单提交了ID,我不想提交项目名称 我发现这很难解释,所以这里有一个很长的版本 详细解释 我有一个模型,它制作了表nutrionalvalues,它有两列

我正在使用Flask制作一个web应用程序

简而言之:当我们提交一个使用QuerySelectField+sqlalchemy query填充选择框的表单时,提交的实际值似乎是主键,但是如果我需要提交另一个值怎么办?假设一个表有两列,ID和Item,现在ID是主键,但是用户选择行不是按主键ID而是按项,这是他们看到的项名称,而不是主键ID。但是表单提交了ID,我不想提交项目名称

我发现这很难解释,所以这里有一个很长的版本

详细解释

我有一个模型,它制作了表nutrionalvalues,它有两列,“id”是主键,“item”列保存食物类型的名称

class nutritionalvalues(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    item = db.Column(db.String(200), nullable=False)

    def __repr__(self):
        return '{}'.format(self.item)
现在使用sqlalchemy和烧瓶表单

def choice_query():
    return nutritionalvalues.query

class ChoiceForm(FlaskForm):
    item = QuerySelectField(query_factory=choice_query, allow_blank=False)
我制作了一个“ChoiceForm”类,并用它来制作一个表单

form = ChoiceForm()
return render_template('index.html', form=form)
在index.html模板中,我有标记

    <form action="/" method="POST">
        {{ form.csrf_token }}
        {{ form.item }}
        <input type="submit" value="Add Item">
    </form>
所以html呈现如下

<form action="/" method="POST">
    <select id="item" name="item">
        <option value="1">bread</option>
        <option value="2">salmon</option>
        <option value="3">pork</option>
    </select>
    <input type="submit" value="Add Item">
 </form>
我不想输入“1”作为我刚吃的食物,我想输入“面包”


那么,在提交表单时,如何使用QuerySelectField+sqlalchemy查询工具包传回实际的项目名称呢?

答案与您使用
get\u label
所做的非常相似,其中
get\u label
接受字符串属性名称,或一个可调用的参数,对象被传递到该参数以派生标签

从:

在大多数情况下,主键将从中自动检测 模型,交替传递一个可调用的单参数,以获取 返回唯一的可比较键

有些不一致的是,
get\u pk
参数不接受字符串属性名称,只接受一个可调用的参数,但本质上做了相同的事情(传递给
get\u label
的字符串被转换为一个可使用
操作符.attrgetter()调用的参数。因此,您可以通过向
get\u pk
传递一个可调用函数来控制用于标识所选选项的对象字段,例如,
get\u pk=operator.attrgetter(“item”)
,或
get\u pk=lambda x:x.item
将为您保存导入


如果您打算以这种方式使用它,以确保在有人添加一个名称已经存在的项目时,不会有虫子爬进来,那么您可能需要对
营养价值设置一个唯一的约束。item

您好,谢谢,是的,我确实看到了get_pk,但我的问题是,肯定会添加一些已经存在的项目,这是一个食品日志,我每天都会吃“面包”,所以“面包”会被添加很多次。用于填充选择框的数据都是唯一的,即在我的食物“nutrionalvalues”表中有一个“面包”项目,但如果选中,表单会将“面包”项目放入“Eated”表中,因此这将在我每次吃面包时发生。添加“get_pk=operator.attrgetter”(“项目”)时也会发生'对于QuerySelectFeild参数列表,它给出了错误'nameError:name'operator'未定义'
class ChoiceForm(FlaskForm):
    item = QuerySelectField(query_factory=choice_query, allow_blank=False, get_label='item')
<form action="/" method="POST">
    <select id="item" name="item">
        <option value="1">bread</option>
        <option value="2">salmon</option>
        <option value="3">pork</option>
    </select>
    <input type="submit" value="Add Item">
 </form>
if request.method == 'POST':
    food_item = request.form['item']
    new_food = eaten(item=food_item)

    try:
        db.session.add(new_food)
        db.session.commit()
        return redirect('/')