django - 如何使用 Django 模拟 POST 到 URL
问题描述
我想创建一个视图函数来模拟用户在 处获取表单url
、设置表单的输入变量之一 ( my_flag
) 并提交该表单。我尝试了两种不同的方法,但都失败了。
方法1:使用python请求获取并发布到url
def simulate_post(request):
url = request.build_absolute_uri(reverse('my_app:form_view', args=[666]))
response = requests.get(url)
csrftoken = response.cookies['csrftoken']
print("TOKEN =", csrftoken)
response = requests.post(url, data={'my_flag': True, 'csrftoken': csrftoken}, headers={'Referer': url})
return response
这种方法失败如下。显然我什至没有成功传递 CSRF 令牌:
TOKEN = EXFI2xoKxHounDIRnqdrPwLpdXGe3zuZATErKINTuxJsgzV7Oj6lPP6kzsjQVc7z
Forbidden (CSRF cookie not set.): /form_view/666/
[12/Feb/2021 16:44:02] "POST /form_view/666/ HTTP/1.1" 403 2868
Internal Server Error: /simulate_post/
Traceback (most recent call last):
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
response = self.process_response(request, response)
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'Response' object has no attribute 'get'
方法二:使用 RequestFactory
def simulate_post(request):
url = request.build_absolute_uri(reverse('my_app:form_view', args=[666]))
factory = RequestFactory()
factory.user = request.user
response = factory.get(url)
response = factory.post(url, data={'my_flag': True})
return response
这种方法失败如下:
Internal Server Error: /simulate_post/
Traceback (most recent call last):
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
response = self.process_response(request, response)
File "/Users/me/.local/share/virtualenvs/myapp-MCS7ouoX/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'WSGIRequest' object has no attribute 'get'
在这两种情况下,我的模拟 POST 似乎都没有返回正确的响应。我怎样才能让它工作?
更新:方法 3 [不完整]
遵循@schillingt 和 Iain 的建议来重构我试图利用的搜索/表单视图的内容,如果我知道如何继续,这是第三种可能的方法。
发出第一个 HTTP 请求,即 GET,基本上相当于这样:
context = search_context(request, data)
return render(request, 'myapp/display.html', context)
这context
包括一个form
变量,它是搜索的形式。如果我可以根据需要设置表单并变成request
POST,它将产生我需要的内容。虽然不知道怎么...
解决方案
您可以使用resolve
来获取将为给定 url 调用的实际视图函数。将从 a 生成的 POST 请求传递给由RequestFactory
返回的视图resolve
应该可以工作
from django.shortcuts import reverse
from django.test import RequestFactory
from django.urls import resolve
def simulate_post(request):
url = reverse('my_app:form_view', args=[666])
factory = RequestFactory()
post_request = factory.post(url, data={'my_flag': True})
resolved = resolve(url)
return resolved.func(post_request, *resolved.args, **resolved.kwargs)
推荐阅读
- python - 如何有效地在一个上限宽度水平写入 6 行卦?
- python - 如何在 tkinter 中禁用绑定到自己框架的其他两个单选按钮
- javascript - 我怎样才能访问从这个承诺返回的数据?
- html - 使用 Laravel 为 foreach 循环中的每个复选框创建一个表单
- php - 一种获取单个数组的简单方法,该数组包含 PHP 中嵌套对象中包含的所有整数
- bash - Git 在 npm 脚本中使用动态分支名称向上游推送
- javascript - 无法访问 iframe 样式的高度和宽度并使用 JavaScript 进行更改
- powerbi - Running total based on other columns value
- raspberry-pi3 - “apt-get:找不到命令”问题 raspberry pi os 使用 Buildroot 构建
- php - PHP 控制表格在网页上的放置位置