Django:在shell中模拟HTTP请求

nem*_*ign 18 django django-shell

我刚刚了解到,使用Rails可以在控制台中用几行代码模拟HTTP请求.

查看:http://37signals.com/svn/posts/3176-three-quick-rails-console-tips("深入了解您的应用"部分).

用Django有类似的方法吗?会很方便的.

Mar*_*ian 28

你可以使用RequestFactory,允许

  • 将用户插入请求中

  • 将上传的文件插入请求中

  • 将特定参数发送到视图

请注意,您必须同时指定URL和视图类,因此需要额外的代码行而不是使用requests.

from django.test import RequestFactory

request_factory = RequestFactory()
my_url = '/my_full/url/here'  # Replace with your URL -- or use reverse
my_request = request_factory.get(my_url)
response = MyClasBasedView.as_view()(my_request)  # Replace with your view
response.render()
print(response)
Run Code Online (Sandbox Code Playgroud)

要设置请求的用户,请my_request.user = User.objects.get(id=123)在获取响应之前执行类似操作.

要将参数发送到基于类的视图,请执行类似的操作 response = MyClasBasedView.as_view()(my_request, parameter_1, parameter_2)

扩展示例

以下是RequestFactory组合使用这些内容的示例

  • HTTP POST(到url url,功能视图view和数据字典post_data)

  • 上传单个文件(路径file_path,名称file_name和表单字段值file_key)

  • 将用户分配给请求(user)

  • 从url(url_kwargs)传递kwargs字典

SimpleUploadedFile 帮助以对表单有效的方式格式化文件.

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import RequestFactory

request = RequestFactory().post(url, post_data)
with open(file_path, 'rb') as file_ptr:
    request.FILES[file_key] = SimpleUploadedFile(file_name, file_ptr.read())
    file_ptr.seek(0)  # resets the file pointer after the read
    if user:
        request.user = user
    response = view(request, **url_kwargs)
Run Code Online (Sandbox Code Playgroud)

  • RequestFactory有一些缺点,即它命名你的服务器`testserver`然后会导致`ALLOWED_HOSTS`的问题,你可以通过初始化它来修复它`rf = RequestFactory(**{"SERVER_NAME":" localhost","wsgi.url_scheme":"https"})`. (4认同)

Lau*_*Mat 17

我如何模拟来自python命令行的请求是:

一种模拟请求的简单方法是:

>>> from django.urls import reverse
>>> import requests
>>> r = requests.get(reverse('app.views.your_view'))
>>> r.text
(prints output)
>>> r.status_code
200
Run Code Online (Sandbox Code Playgroud)

更新:确保启动django shell(via manage.py shell),而不是经典的python shell.

更新2:对于Django <1.10,将第一行更改为

from django.core.urlresolvers import reverse 
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望在"http:// localhost:8000"之前添加``,以便它读取`requests.get("http://192.168.0.1:8000"+ reverse(...))` (3认同)
  • 当我尝试你的方法时,我得到了这个:`requests.exceptions.MissingSchema:无效的URL'/':没有提供架构.也许你的意思是http:///?` (2认同)
  • 这与仅通过命令行使用 `wget` 或 `curl` 请求它没有任何不同。 (2认同)

Ash*_*ish 5

(参见 tldr;向下)

这是一个老问题,但只是添加一个答案,以防有人感兴趣。

尽管这可能不是最好的(或者说 Django)做事的方式。但你可以尝试这样做。

在你的 django shell 里面

>>> import requests
>>> r = requests.get('your_full_url_here')
Run Code Online (Sandbox Code Playgroud)

解释: 我省略了reverse(), 解释是,因为reverse()或多或少,找到与views.py函数关联的url,reverse()如果您愿意,您可以省略 ,并改为放置整个url。

例如,如果你的django项目中有一个朋友应用程序,并且你想list_all()在朋友应用程序中看到(在views.py中)函数,那么你可以这样做。

太长了;

>>> import requests
>>> url = 'http://localhost:8000/friends/list_all'
>>> r = requests.get(url)
Run Code Online (Sandbox Code Playgroud)