python - 在功能齐全的 django 应用程序中测试 POST 时出现 405 错误

标签 python django post http-status-code-405

我正在 django 中开发一个 Web 应用程序,它使用表单 POST 将用户输入的数据放入数据库中。

问题: 在 django.test.TestCase 中使用 self.client.post() 进行测试返回 405(不允许请求)。

排除:

  • 不允许 POST - 应用程序在运行时成功发布(而不是在运行 tests.py 时)。
  • CSRF 问题 - django.test.TestCase 在运行测试时默认禁用 CSRF 身份验证。
  • 测试总体上被破坏 - 我有几个使用 self.client.get() 可以正常工作的测试

问题: 当我期望得到 302(重定向)时,可能是什么导致了 405?

这是以这种方式失败的测试之一:

def test_process_one_match_in_title(self):
    #TODO: the server is refusing self.client.post requests in testing, although they work in the app proper.  Why?

    #create a user and an abstract
    this_abstract = Abstract.objects.get(pk=5)  #'hypoplasia' in both title and abstract text
    this_annotator = create_annotator("Joe")
    this_annotator.save()

    userMatchesJSON = "{'hypoplasia': 8}"

    resp = self.client.post(reverse('diseaseMatcherApp:abstractDetail', kwargs={'pk': this_abstract.id}),
                            {'inputSoFar': 'hypoplasia', 'abstract_pk': this_abstract.id, 'user.id': this_annotator.id,
                             'userMatches': userMatchesJSON})
    self.assertEqual(resp.status_code, 302)  #FAILS HERE; AssertionError: 405 != 302

最佳答案

这个问题让我很生气,这是搜索该问题时出现的与此主题相关的唯一问题。我不能说我有一个正确的修复方法,但我已经为我解决了它,并且我想我可以分享几个小时的调试结果。

我遇到了与您完全相同的问题,即 POST 请求在单元测试中不起作用,但在完整应用程序运行时却工作得很好。在我的例子中更疯狂的是,测试在我的笔记本电脑上运行,但在我的台式机上运行,​​没有环境差异(相同的虚拟环境,只有 python3.5.3 VS python3.5.1 的细微差别)

我收到的消息是:

  • “不允许的方法 (POST):url/where/i/wanted/to/post”与测试方法名称交错(当使用 ./manage.py test -v2 运行时)
  • “测试总结”中出现断言错误:“AssertionError:False 不是 true:响应未按预期重定向:响应代码为 405(预期为 302)”

使用以下代码:

r = self.client.post(url, follow=True)
self.assertRedirects(r, expected_url)

(我发布的 URL 由 CreateView 派生的类处理)

第一条消息是从 this piece of code 发出的这是通过 this line 触发的

handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

...将 request.method 设置为“POST”...结果我的 CreateView 在测试模式下没有任何“post”方法(这很奇怪...显然在运行时我的笔记本电脑上的 View 具有该功能!),因此 Django 依赖于“http_method_not_allowed”。

现在,为什么我的 CreateView 没有“POST”方法?我没有花时间完成整个初始化过程(这看起来相当复杂),所以我没有确切的想法,但在我的情况下,一些 URL 在我的测试中根本没有“初始化”(我可以通过在 urls/resolvers.py 中打印此函数中的内容来找出)。例如,在运行测试时,应该处理 POST 请求的 URL 确实不存在......所以我想这解释了为什么我的 CreateView 没有正确初始化

我终于发现我的问题来自于使用 django-crudbuilder 应用程序来构建我的 CRUD View ,并且当数据库为空时它无法正确初始化(在非持久数据库上运行测试时就是这种情况) )

不确定在其他情况下这个问题可能来自哪里,但是如果您遇到这种情况,您可能想检查在运行测试时 Django 是否正确“看到”了您的所有 URL(如果它们没有) t,尝试找出原因)。

(我链接的 Django 源代码来自当前的 master,但它与我使用的版本 1.11.7 中所经历的源代码相同)

关于python - 在功能齐全的 django 应用程序中测试 POST 时出现 405 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25793255/

相关文章:

python - ElementNotVisibleException : Python + Selenium, Web 上的登录凭据

python - Django __gt 过滤器返回重复项

php - Codeigniter $this->input->post() 为空而 $_POST 正常工作

mysql - Python3 中的 Django 数据库

python - manage.py runserver 不终止

ios - 将数据发布到这种格式?

php - 发送文件 POST C++

python - Django:DecimalField 值显示

python - 如何显示另一个.py文件调用的窗口?

python - 为什么赋值时的行为不一致?