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

相关问题