[英]python - Handle column names in form for update query with Flask-SQLAlchemy
我正在使用Flask和SQLAlchemy,我想编写一个HTML表单来执行数据库更新。 但是,为了方便起见,我希望用户构建查询:
从一个select
,用户选择要修改的列,在input
他插入新值,从第二个select
他选择where
子句的列,并在最后一个输入文本中插入条件的值。
从逻辑的角度来看,我想到了这样的事情:
exhb = Exhibition.query.filter_by (request.form.get ('wh') = request.form ['cond']). first ()
exhb.request.form.get ('columns') = Request.Form ['val']
db.session.commit ()
但它返回:
SyntaxError: keyword can not be an expression
我尝试使用两个变量来分配wh
和columns
但是,尽管正确读取了该值,但它返回了我:
Entity '<class' connect.Exhibition '>' has no property 'wh'
然后,如何简单地获取要在查询中使用的两列的名称? 有内置的方法可以做到这一点吗?
我建议您先查询数据库,然后将行ID作为html中的select值传递
在烧瓶应用中
@app.route('/exhibition', methods=['GET', 'POST'])
def exhibition():
options = session.query(Exhibition) #however you query your db
return render_template('exhibition.html', options = options)
在您的html中(我猜您正在使用jinja作为模板)
<select>
{%for option in options%}
<option value={{option.id}}>{{option.text}}</option>
{endfor}
</select>
然后,您可以获取要通过行ID修改的行,该行ID是在发布表单时获得的。
然后,当您更新行时,请确保您指定要更新的特定列,例如
row_to_edit = session.query(Exhibition).filter_by(id = request.form ['input_field']))
#specify what you are updating
row_to_edit.column_to_update = request.form ['input_field']
# Then you can comit column_to_edit
为了确保编辑人员易于识别列名,并减轻必须验证与列名匹配的自由文本条目的负担,我建议您添加第二个选择字段来显示列名,以便文本输入仅用于列值上面的视图变为
@app.route('/exhibition', methods=['GET', 'POST'])
def exhibition():
options = session.query(Exhibition) #however you query your db
cols = Exhibition.__table__.columns
return render_template('exhibition.html', options = options, cols = cols)
第二选择
<select>
{%for col in cols%}
<option value={{col.key}}>{{col.key}}</option>
{endfor}
</select>
您可以通过遍历cols并给出带有选项值和可读文本的列表来使选项文本更具可读性
这样指定您要更新的列
row_to_edit.getattr(row_to_edit, request.form ['select_field_for_column'] = request.form ['input_field_column_value']
我知道第一部分令人困惑。 通常,您可以执行row_to_edit.column_to_update,但是由于在本例中,要更新的列是变量,因此我们使用getattr()获取等于该变量的col名称。
如果您熟悉wtforms,或者您是一个快速学习者,他们将为您提供更优雅的处理方式
过滤器调用中的request.form.get()
调用形成一个表达式( 请参阅docs ),这是不允许的。 结果, filter_by()
和filter()
期望关键字参数等于运算符的左侧。
也就是说,如果您在此处放置一个函数调用(在您的情况下为request.form.get()
),Python会引发keyword can not be an expression
错误。 换句话说,您不能直接使用表单请求的结果。
相反,您将需要在代码中显式传递关键字参数。 假设您已经在表单中显示了列选项的预设列表,则可以在视图函数中使用以下类似的方法显式地处理这组选项:
def query_construction_view():
....
wh = request.form.get('wh')
cond = request.form['cond']
if wh == 'column_option1':
exhb = Exhibition.query.filter_by(column_option1=cond)
....
elif wh == 'column_option2':
exhb = Exhibition.query.filter_by(column_option2=cond)
....
# etc.
请注意,每个filter_by()
调用中的等号左侧都是关键字,而不是函数调用或字符串。 还要注意,您可以在右侧使用变量和表达式,即cond
参数取自表单输入。
这不是最可扩展的解决方案,因为关键位是硬编码的。 我不知道您的用例是什么,但是使用像Flask-Admin这样的预打包数据库前端来处理数据库交互可能会更好地为您服务。
有关filter()
和filter_by()
更多信息,请参见SQLAlchemy Query API 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.