【问题标题】:Flask - Convert request.args to dictFlask - 将 request.args 转换为 dict
【发布时间】:2013-11-09 21:35:33
【问题描述】:

我一直在试图弄清楚如何将 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 - 您可以将 dict 传递给过滤器函数。

任何想法我做错了什么?

非常感谢:)

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

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'],)

有什么想法吗?

【问题讨论】:

    标签: sqlalchemy flask flask-sqlalchemy


    【解决方案1】:

    你可以:

    http://localhost:5000/filter-test?var=test

    query_dict = request.args.to_dict()
    
    print(query_dict)
    {'var': 'test'}
    
    print(query_dict['var'])
    var
    

    【讨论】:

    • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
    【解决方案2】:

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

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

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

    【讨论】:

    • 这是正确答案。补充一点:使用request.args.to_dict() 是正确的,而dict(request.args) 则不是,因为它会生成一个字典,其值由列表组成。
    【解决方案3】:

    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,可以免费获得上面的sn-p)

    【讨论】:

      【解决方案4】:

      使用filter_by:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-30
        • 2019-01-19
        • 1970-01-01
        • 2014-06-18
        • 2018-10-14
        • 2019-09-27
        • 2019-10-08
        相关资源
        最近更新 更多