我正在使用Flask制作网络应用。
简而言之::当我们提交使用QuerySelectField + sqlalchemy查询填充选择框的表单时,所提交的实际值似乎是主键,但是如果我需要提交该怎么办?另一个价值?假设一个表有两列,即ID和Item,现在ID是主键,但是用户不是通过主键ID而是通过Item选择行,这就是他们看到的项名称,而不是主键ID。但是表单提交了ID,我不想提交项目名称。
我觉得很难解释,所以这里是长版
详细解释
我有一个模型,该模型使表的营养价值具有两列,“ 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和flaskforms
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"><nutritionalvalues 1></option>
<option value="2"><nutritionalvalues 2></option>
<option value="3"><nutritionalvalues 3></option>
</select>
<input type="submit" value="Add Item">
</form>
现在说我使用'get_label'参数,我可以将选择选项更改为实际项目
class ChoiceForm(FlaskForm):
item = QuerySelectField(query_factory=choice_query, allow_blank=False, get_label='item')
因此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”,但是我希望它返回“面包”
因为我随后将其用于将此数据输入到另一个表中,如下所示
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('/')
我不想输入“ 1”作为我刚吃的食物,我想输入“面包”。
那么提交表单时,如何使用QuerySelectField + sqlalchemy查询工具包将实际的项目名称传递回去?
答案 0 :(得分:1)
答案非常类似于您对get_label
所做的操作,其中get_label
要么接受字符串属性名称,要么接受传递给对象以导出对象的一个参数标签。
在大多数情况下,主键会从 模型,或者将一个可调用参数传递给get_pk,该参数可以 返回唯一的可比较键。
有些矛盾的是,get_pk
参数不接受字符串属性名称,只能接受一个参数,但是本质上是相同的(将传递给get_label
的字符串转换为一个-可使用operator.attrgetter()
[source]调用的参数)。因此,您可以通过将可调用对象传递到get_pk
,例如get_pk=operator.attrgetter("item")
或get_pk=lambda x: x.item
来控制用于标识所选选项的对象字段,以节省导入。>
如果您打算以这种方式使用nutritionalvalues.item
,则可能要对其施加唯一约束,以确保在有人添加名称已经存在的项目时,不会出现任何错误。