2015-02-09 121 views
6

可以說我有這個APIViewDjango的REST框架APIRequestFactory申請對象有沒有屬性「query_params」

class Dummy(APIView): 
    def get(self, request): 
     return Response(data=request.query_params.get('uuid')) 

爲了測試它,我需要創建一個請求對象傳遞到get功能

def test_dummy(self): 
    from rest_framework.test import APIRequestFactory 
    factory = APIRequestFactory() 
    request = factory.get('/?uuid=abcd') 
    DummyView().get(request) 

它抱怨AttributeError: 'WSGIRequest' object has no attribute 'query_params'

仔細一看,工廠創建了一個WSGIRequest實例,而不是DRF版本<class 'rest_framework.request.Request'>

>>> from rest_framework.test import APIRequestFactory 
>>> factory = APIRequestFactory() 
>>> request = factory.get('/') 
>>> request.__class__ 
<class 'django.core.handlers.wsgi.WSGIRequest'> 

回答

10

沒錯。此刻,APIRequestFactory返回HttpRequest對象,只有在對象進入視圖層後纔會升級到REST框架Request對象。

這反映了您在實際請求中會看到的行爲,以及它在確實處理的行爲是如何處理的。呈現JSON,XML或您爲測試請求配置的任何其他內容類型。

不過,我同意,這是令人驚訝的行爲,在某些時候它可能會返回一個Request對象,其餘的框架視圖將確保只執行的請求的HttpRequest該實例Request升級。

你需要在你的情況做的是實際上調用視圖,而不是調用.get()方法...

factory = APIRequestFactory() 
request = factory.get('/?uuid=abcd') 
view = DummyView.as_view() 
response = view(request) # Calling the view, not calling `.get()` 
+0

對我來說:我在一個基於django類的視圖中使用了一個序列化器,並得到了上面提到的異常。 reasion:non-drf請求被髮送到序列化上下文/ – patroqueeet 2015-12-16 20:36:18

12

參考湯姆的解決方案,DummyView()(request)將引發錯誤:

TypeError: 'DummyView' object is not callable 

相反,應該使用as_view就像你在urls.py中做的那樣:

DummyView.as_view()(request) 

DRF的as_view使用method initialize_request將Django請求對象轉換爲DRF版本。您可以試試:

from rest_framework.views import APIView 
APIView().initialize_request(request) 
>>> <rest_framework.request.Request object at 0xad9850c> 

您還可以使用APIClient來運行測試。它也測試URL調度。

from rest_framework.test import APIClient 
client = APIClient() 
client.post('/notes/', {'title': 'new idea'}, format='json') 
+0

確實是的,我是愚蠢的 - 現在更新我的答案,謝謝! – 2015-02-10 12:07:36

+7

雖然我接受了Tom的回答,因爲它直接回答了我的問題,'initialize_request'提示實際上可以幫助很多人。 – 2015-02-10 19:23:51

相關問題