繁体   English   中英

python-使用Flask-SQLAlchemy处理表单中的列名称以进行更新查询

[英]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

我尝试使用两个变量来分配whcolumns但是,尽管正确读取了该值,但它返回了我:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM