【问题标题】:Flask test_client removes query string parametersFlask test_client 删除查询字符串参数
【发布时间】:2015-01-20 20:48:21
【问题描述】:

我正在使用 Flask 创建几个非常简单的服务。通过查询字符串从外部测试(使用 HTTPie)参数进入服务。

但如果我使用类似的东西。

    data = {
        'param1': 'somevalue1',
        'param2': 'somevalue2'}

    response = self.client.get(url_for("api.my-service", **data))

我可以看到正在创建的正确 URI:

http://localhost:5000/api1.0/my-service?param1=somevalue1&param2=somevalue2

当我断点进入服务时:

request.args

实际上是空的。

self.client 是通过在我配置的 Flask 应用程序上调用 app.test_client() 创建的。

任何人都知道为什么? 之后的任何东西都被丢弃了,或者如何在仍然使用test_client 的同时解决它?

【问题讨论】:

    标签: python testing flask


    【解决方案1】:

    我刚刚找到了一种解决方法。

    制作

    data = {
        'param1': 'somevalue1',
        'param2': 'somevalue2'}
    
    response = self.client.get(url_for("api.my-service", **data))
    

    进入这个:

    data = {
        'param1': 'somevalue1',
        'param2': 'somevalue2'}
    
    response = self.client.get(url_for("api.my-service"), query_string = data)
    

    这可行,但似乎有点不直观,调试有一个地方,URI中提供的查询字符串被丢弃....

    但无论如何,这暂时有效。

    【讨论】:

      【解决方案2】:

      我知道这是一个旧帖子,但我也遇到了这个。在烧瓶github repository 中有一个关于此的未解决问题。看来这是预期的行为。来自问题线程中的回复:

      mitsuhiko 于 2013 年 7 月 24 日发表评论
      这是当前的预期行为。测试客户端的第一个参数应该是一个相对 url。如果不是,则删除参数,因为它被视为与第二个连接的 url。这有效:

      >>> from flask import Flask, request
      >>> app = Flask(__name__)
      >>> app.testing = True
      >>> @app.route('/')
      ... def index():
      ...  return request.url
      ... 
      >>> c = app.test_client()
      >>> c.get('/?foo=bar').data
      'http://localhost/?foo=bar'
      

      将绝对 url 转换为相对 url 并保留查询字符串的一种方法是使用 urlparse:

      from urlparse import urlparse
      
      absolute_url = "http://someurl.com/path/to/endpoint?q=test"
      parsed = urlparse(absolute_url)
      path = parsed[2] or "/"
      query = parsed[4]
      relative_url = "{}?{}".format(path, query)
      
      print relative_url
      

      【讨论】:

        【解决方案3】:

        如果您正在尝试除 GET 之外的任何其他 HTTP 方法

        response = self.client.patch(url_for("api.my-service"), query_string=data,
                                     data="{}")
        

        data="{}"data=json.dumps({}) 应该在那里,即使正文中没有内容。否则,会导致 BAD Request。

        【讨论】:

          【解决方案4】:

          对我来说,解决方案是在 with 语句中使用客户端:

          with app.app_context():
              with app.test_request_context():
                  with app.test_client() as client:
                      client.get(...)
          

          而不是

          client = app.test_client()
          client.get(...)
          

          我将测试客户端的创建放在一个夹具中,以便为每个测试方法“自动”创建:

          from my_back_end import MyBackEnd
          
          sut = None
          app = None
          client = None
          
          @pytest.fixture(autouse=True)
          def before_each():
              global sut, app, client
              sut = MyBackEnd()
              app = sut.create_application('frontEndPathMock')
              with app.app_context():
                  with app.test_request_context():                
                      with app.test_client() as client:
                          yield
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-05-05
            • 1970-01-01
            • 2022-01-22
            • 2012-08-30
            • 2020-11-13
            • 1970-01-01
            • 2021-09-01
            • 2014-09-06
            相关资源
            最近更新 更多