如何使用Django模拟到URL的帖子
我想创建一个视图函数,模拟用户在如何使用Django模拟到URL的帖子,django,django-views,django-forms,csrf,httpresponse,Django,Django Views,Django Forms,Csrf,Httpresponse,我想创建一个视图函数,模拟用户在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 = res
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'
方法2:使用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'
在这两种情况下,我似乎都没有从我的模拟帖子中回复正确的回复。我怎样才能让它工作
更新:方法3[不完整]
按照@schillingt和Iain的建议,重构我试图利用的搜索/表单视图的核心,如果我知道如何进行,这里有第三种可能的方法
发出第一个HTTP请求GET基本上相当于以下内容:
context = search_context(request, data)
return render(request, 'myapp/display.html', context)
该
上下文
包含一个表单
变量,该变量是用于搜索的表单。如果我能按照自己的意愿设置表单,并将请求
转换为帖子,它将生成我所需的内容。不确定如何…输入的名称是csrfmiddlewaretoken
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, 'csrfmiddlewaretoken': csrftoken}, headers={'Referer': url})
return response
您可以使用获取将为给定url调用的实际视图函数。将从RequestFactory
生成的POST请求传递到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)
这是为了测试吗?不,这是为了网站本身。表单基本上是用于过滤搜索的,我想要一个视图函数来运行以特定方式填写表单的搜索。您可以共享搜索/表单视图的代码吗?移动接收表单数据并生成对共享函数的响应的代码,您可以将硬编码值传递给共享函数,这可能会有意义。如果这在同一个应用程序中,我将避免向其他URL发出请求,而是将该逻辑重构为一个公共函数,并在此处直接使用它。似乎没有必要在此视图中包含另一个HTTP请求。感谢您的回复,@schillingt和Iain。如果这是一个简单的搜索/表单视图,我肯定会选择这条路线。问题在于搜索视图是允许加载自定义类和模板的通用系统的一部分,而这些类目前没有允许传入自定义变量的接口。我可以加上它,也许在某个时候应该加上它,但我希望有一个简单直接的解决方案来解决这个问题。对不起,我也试过了,方法1的结果完全一样。这真的很接近了!我不得不在
post\u request=
行之后添加post\u request.user=request.user
,这样搜索视图就可以工作了,但它现在确实成功地执行了搜索并正确地显示了设置的表单。唯一缺少的似乎是CSRF令牌。当我对生成的表单进行另一次搜索时,搜索失败,出现错误:禁止(CSRF令牌丢失或不正确)。