为什么向烧瓶中的功能添加请求,导致错误请求'在空POST?

时间:2017-10-21 06:42:23

标签: python flask request http-post

在为我的Flask应用程序组合测试时,我偶然发现了我无法理解的行为。在我的测试中,我使用Flask documentation建议的方法来从测试中访问和修改session

说我有非常基本的项目结构:

root
|-- my_app.py
|-- tests
    |-- test_my_app.py

my_app.py

from flask import (
    Flask,
    session,
    request
    )

app = Flask(__name__)
app.secret_key = 'bad secret key'

@app.route('/action/', methods=['POST'])
def action():
    the_action = request.form['action']
    if session.get('test'):
        return 'Test is set, action complete.'
    else:
        return 'Oy vey!'

test_my_app.py

import flask

from unittest import TestCase
import my_app

class TestApp(TestCase):

    def setUp(self):
        self.test_client = my_app.app.test_client()

    def testUnsetKeyViaPostNegative(self):
        with self.test_client as client:
            response = client.post('/action/')
            expected_response = 'Oy vey!'.encode('ascii')
            self.assertTrue(expected_response == response.data)

现在,如果我运行测试,它将失败,因为响应返回400 Bad Request。如果the_action = request.form['action']得到表扬,一切顺利。

我需要它的原因是因为app中存在逻辑(以及随后的测试),这取决于收到的data(为简洁起见,我省略了它)。

我认为将the_action = request.form['action']更改为类似the_action = request.form['action'] or ''的内容可以解决问题,但它不会成功。一个简单的解决方法是在帖子请求中添加一些存根data,如response = client.post('/action/', data=dict(action='stub'))

我觉得我觉得如何从测试工作中访问和修改会话时遗漏了一些重要的观点,因此我无法理解所描述的行为。

我想了解的是:

  1. 为什么只是从请求中获取数据而不添加任何其他逻辑(即行the_action = request.form['action']导致400 Bad RequestPOST
  2. 为什么不会the_action = request.form['action'] or ''the_action = request.form['action'] or 'stub'解决问题,在我看来,情况就好像空字符串或'stub'是通过POST发送的?< / LI>

1 个答案:

答案 0 :(得分:0)

基于chrisanswer to the linked question的评论,我现在看到这个问题基本上是What is the cause of the Bad Request Error when submitting form in Flask application?的重复

解决当前问题的问题点:

  1. 如果Flask无法从argsform词典中找到任何键,则会引发HTTP错误(在这种情况下为400 Bad Request)。无论获取密钥是否以任何方式影响应用程序的逻辑(即仅将其分配给变量the_action = request.form['action']将导致HTTP错误,如果action中不存在form密钥)。
  2. Sean Vieiralinked question

    的评论总结了这一点
      

    当无法在args中找到密钥并形成字典时,Flask会引发HTTP错误。

    1. the_action = request.form['action'] or ''the_action = request.form['action'] or 'stub'是不够的,因为Flask会尝试在request.form['action']中获取一个不存在的密钥,因为它不存在而失败并导致400 Bad Request,在它到达or之前。有了这个说法 - 永远不会达到 or ,好像request.form['action']中有一个值 - the_action将被分配给此值,否则{{1将被退回。
    2. 为避免这种情况 - 应使用字典的400 Bad Request方法,并将默认值传递给它。因此get()变为the_action = request.form['action'] or 'stub'。这样,空POST不会导致the_action = request.form.get('action', 'stub')错误。