Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Django模拟到URL的帖子_Django_Django Views_Django Forms_Csrf_Httpresponse - Fatal编程技术网

如何使用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令牌丢失或不正确)。