[英]POST document with Django RequestFactory instead of form data
我想構建一個測試中間件的請求,但我不希望 POST 請求總是假設我正在發送表單數據。 有沒有辦法在django.test.RequestFactory
生成的請求上設置request.body
?
即,我想做類似的事情:
from django.test import RequestFactory
import json
factory = RequestFactory(content_type='application/json')
data = {'message':'A test message'}
body = json.dumps(data)
request = factory.post('/a/test/path/', body)
# And have request.body be the encoded version of `body`
上面的代碼將無法通過測試,因為我的中間件需要將數據作為request.POST
中的文檔而不是request.body
中的表單數據傳遞。 但是, RequestFactory
始終將數據作為表單數據發送。
我可以用django.test.Client
做到這一點:
from django.test import Client
import json
client = Client()
data = {'message':'A test message'}
body = json.dumps(data)
response = client.post('/a/test/path/', body, content_type='application/json')
我想對django.test.RequestFactory
做同樣的事情。
RequestFactory具有對JSON負載的內置支持。 您無需先轉儲數據。 但是您應該將內容類型傳遞給post
,而不是實例化。
factory = RequestFactory()
data = {'message':'A test message'}
request = factory.post('/a/test/path/', data, content_type='application/json')
我已經嘗試過傑伊的解決方案,但是沒有用,但是經過一番研究,它做到了(Django 2.1.2)
factory = RequestFactory()
request = factory.post('/post/url/')
request.data = {'id': 1}
在更高版本的 Django(在 4.0 上測試)中,這不再是問題。 另一方面,將數據傳遞給request.POST
可能是。
默認情況下,將content-type
傳遞給 RequestFactory 時,數據會進入request.body
,如果不這樣做,數據會進入request.POST
。
request_factory = RequestFactory()
# provide content-type
request = request_factory.post(f'url', data={'foo': 'bar'}, content_type="application/json")
ic(request.body) # b'{"foo": "bar"}'
# don't provide content type
request = request_factory.post(f'url', data={'foo': 'bar'})
ic(request.POST) # <QueryDict: {'foo': ['bar']}>
以下是 Django 4.1 中對我有用的內容:
from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase, RequestFactory
from customauth import views
class RegistrationViewTest(TestCase):
def setUp(self):
self.factory = RequestFactory()
def test_post_request_creates_new_user(self):
data = {
'email': 'new_user@email.com',
'screen_name': 'new_user',
'password1': 'new_user_password',
'password2': 'new_user_password',
}
request = self.factory.post('/any/path/will/do/', data )
middleware = SessionMiddleware(request)
middleware.process_request(request)
request.session.save()
response = views.registration_view(request)
self.assertEqual(response.status_code, 302)
# ok
這個測試通過。 表單已在views.registration_view
中成功處理。
筆記:
self.factory.post
的調用中包含content_type='application/json'
時(正如接受的答案所暗示的那樣), request.POST
在視圖中沒有內容。 沒有它,它就起作用了。 我不知道為什么,但很樂意學習。SessionMiddleware
來request
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.