Flask - 将request.args转换为dict

时间:2013-10-30 10:45:34

标签: sqlalchemy flask flask-sqlalchemy

我一直在试图弄清楚如何将request.args传递给sqlalchemy过滤器。

我认为这应该有效:

model.query.filter(**request.args).all()

但它正在抛出错误:

TypeError: <lambda>() got an unexpected keyword argument 'userid'

当存在userid或任何其他get arg时。

根据这篇文章 - https://stackoverflow.com/questions/19506105/flask-sqlalchemy-query-with-keyword-as-variable - 你可以将一个字典传递给过滤函数。

任何想法我做错了什么?

非常感谢:)

更新:非常感谢下面的海报,但是现在它引发了以下错误:

ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY tblclients.clientname' at line 3") 'SELECT favourites.id AS favourites_id, favourites.userid AS favourites_userid, favourites.clientid AS favourites_clientid, favourites.last_visit AS favourites_last_visit \nFROM favourites INNER JOIN tblclients ON tblclients.clientid = favourites.clientid \nWHERE favourites.userid = %s ORDER BY tblclients.clientname' ([u'41'],)

有什么想法吗?

3 个答案:

答案 0 :(得分:8)

首先,您必须使用filter_by,而不是filter

其次,Flask request.args使用MultiDict,一个带有列表中值的dict,允许同一个键有多个值,因为同一个字段在查询字符串中可以出现多次。您收到错误是因为SQL查询得到[u'41']时只能预期'41'。您可以使用request.args.to_dict()来解决此问题:

model.query.filter_by(**request.args.to_dict()).all()

答案 1 :(得分:4)

使用filter_by

model.query.filter_by(**request.args).all()

filter的使用方式如下:query.filter(Class.property == value)filter_by的使用方式如下:query.filter_by(property=value)(第一个是表达式,后一个是关键字参数)

答案 2 :(得分:1)

filter_by(**request.args)如果你有非模型查询参数,例如page用于分页,则效果不佳,否则会出现以下错误:

InvalidRequestError: Entity '<class 'flask_sqlalchemy.JobSerializable'>' has no property 'page'

我使用类似这样的东西来忽略不在模型中的查询参数:

    builder = MyModel.query
    for key in request.args:
        if hasattr(MyModel, key):
            vals = request.args.getlist(key) # one or many
            builder = builder.filter(getattr(MyModel, key).in_(vals))
    if not 'page' in request.args:
        resources = builder.all()
    else:
        resources = builder.paginate(
            int(request.args['page'])).items

考虑一个名为valid的列的模型,这样的东西会起作用:

curl -XGET "http://0.0.0.0/mymodel_endpoint?page=1&valid=2&invalid=whatever&valid=1"

invalid将被忽略,page可用于分页,最重要的是,将生成以下SQL:WHERE mymodel.valid in (1,2)

(如果您使用此boilerplate-saving module

,请免费获取上述代码段