【问题标题】:Why does the Flask bool query parameter always evaluate to true?为什么 Flask bool 查询参数总是评估为真?
【发布时间】:2021-04-11 00:29:27
【问题描述】:

我的 Flask 应用程序中的一个端点有一个奇怪的行为,它接受布尔查询参数。无论我传递给它什么,例如asfsdfdtruefalse,都认为是真的。只有留空才会变成假。

full_info = request.args.get("fullInfo", default=False, type=bool)
if full_info:
    # do stuff

似乎任何输入都被认为是真实的。有什么方法可以使用 Flask 定义类型的预期方式,还是我需要接受一个字符串并进行比较?

【问题讨论】:

    标签: python python-3.x flask


    【解决方案1】:

    这是预期的,因为查询字符串是一个实际的字符串,因此当你得到一个字符串时,不管它是什么,如果它不为空,它就是真的。 如:

    >>>bool('False')
    True
    

    如果你想得到一个布尔值,你必须进行字符串比较。

    【讨论】:

      【解决方案2】:

      一个“技巧”是将json.loads 用作type。它将充当“工厂”,从字符串 'true'/'false' 构建一个 bool True/False

      【讨论】:

      • 如果传递的参数是'True'/'False',这将不起作用(尽管这本身可能是前端使用大写 T/F 的错误)。
      • 好吧,如果你需要处理更多的极端情况,基本的“真”->“真”,“假”->假,那么你只需要编写一个带有自定义逻辑的函数来翻译查询参数作为字符串(“true”、“false”、“True”、“yes”、“no”、“0”、“1”、“one”等)到布尔值 True / False .
      【解决方案3】:

      request.args.gettype 参数有点误导,因为它不是用于指定值的类型,而是用于指定 可调用

      • type – 用于在 MultiDict 中转换值的可调用对象。如果此可调用对象引发 ValueError,则返回默认值。

      它接受一个可调用对象(例如一个函数),将该可调用对象应用于查询参数值,然后返回结果。所以代码

      request.args.get("fullInfo", default=False, type=bool)
      

      调用bool(value),其中value 是查询参数值。但在 Flask 中,查询参数值始终存储为字符串。不幸的是,在非空字符串上调用 bool() 将始终是 True

      In [10]: bool('true')
      Out[10]: True
      
      In [11]: bool('false')
      Out[11]: True
      
      In [12]: bool('any non-empty will be true')
      Out[12]: True
      
      In [13]: bool('')
      Out[13]: False
      

      除了bool,您可以传递一个函数来显式检查字符串是否等于文字字符串true(或您的API规则认为是真实的任何值):

      full_info = request.args.get('fullInfo', default=False, type=lambda v: v.lower() == 'true')
      
      return jsonify({'full_info': full_info})
      
      $ curl -XGET http://localhost:5000/test?fullInfo=false
      {"full_info":false}
      
      $ curl -XGET http://localhost:5000/test?fullInfo=adasdasd
      {"full_info":false}
      
      $ curl -XGET http://localhost:5000/test?fullInfo=11431423
      {"full_info":false}
      
      $ curl -XGET http://localhost:5000/test?fullInfo=
      {"full_info":false}
      
      $ curl -XGET http://localhost:5000/test?fullInfo=true
      {"full_info":true}
      
      $ curl -XGET http://localhost:5000/test?fullInfo=TRUE
      {"full_info":true}
      
      $ curl -XGET http://localhost:5000/test
      {"full_info":false}
      

      【讨论】:

        【解决方案4】:

        如果你使用 flask_restplus.inputs.boolean 类型而不是 bool,它会正常工作。 这是解释here。 https://github.com/noirbizarre/flask-restplus/issues/199#issuecomment-276645303

        【讨论】:

          猜你喜欢
          • 2018-07-01
          • 2014-05-19
          • 1970-01-01
          • 2015-12-07
          • 1970-01-01
          • 2016-10-03
          • 1970-01-01
          • 2014-02-16
          • 1970-01-01
          相关资源
          最近更新 更多