簡體   English   中英

使用 Django RequestFactory 而不是表單數據的 POST 文檔

[英]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在視圖中沒有內容。 沒有它,它就起作用了。 我不知道為什么,但很樂意學習。
  • 我需要手動添加SessionMiddlewarerequest

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM