【发布时间】:2015-07-13 20:21:08
【问题描述】:
我正在使用 Django 和 REST 框架开发一个 REST api。我有一个使用这种 json 接受 POST 请求的端点:
{
"pipeline": ["Bayes"],
"material": [
"Rakastan iloisuutta!",
"Autojen kanssa pitää olla varovainen.",
"Paska kesä taas. Kylmää ja sataa"
]
}
它是一个机器学习分析 api,json 告诉使用贝叶斯分类器提供字符串并返回结果。当我通过发布请求手动测试它时,这很好用。但是,当我尝试编写单元测试时,它会崩溃。我有以下测试:
class ClassifyTextAPITests(APITestCase):
fixtures = ['fixtures/analyzerfixtures.json'] #suboptimal fixture since requires bayes.pkl in /assets/classifiers folder
def test_classification(self):
""" Make sure that the API will respond correctly when required url params are supplied.
"""
response = self.client.post(reverse('analyzer_api:classifytext'), {
"pipeline": ["Bayes"],
"material": [
"Rakastan iloisuutta!",
"Autojen kanssa pitää olla varovainen.",
"Paska kesä taas. Kylmää ja sataa",
]
})
self.assertTrue(status.is_success(response.status_code))
self.assertEqual(response.data[0], 1)
测试每次都失败,因为后一个断言给出“AssertionError:'P'!= 1”
这是我的查看代码:
class ClassifyText(APIView):
"""
Takes text snippet as a parameter and returns analyzed result.
"""
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.AllowAny,)
parser_classes = (JSONParser,)
def post(self, request, format=None):
try:
self._validate_post_data(request.data)
print("juttu", request.data["material"])
#create pipeline from request
pipeline = Pipeline()
for component_name in request.data["pipeline"]:
pipeline.add_component(component_name)
response = pipeline.execute_pipeline(request.data['material'])
status_code = status.HTTP_200_OK
except Exception as e:
response = {"message": "Please provide a proper data.",
"error": str(e) }
status_code = status.HTTP_400_BAD_REQUEST
return Response(response, status=status_code)
def _validate_post_data(self, data):
if "pipeline" not in data:
raise InvalidRequest("Pipeline field is missing. Should be array of components used in analysis. Available components at /api/classifiers")
if len(data["pipeline"]) < 1:
raise InvalidRequest("Pipeline array is empty.")
if "material" not in data:
raise InvalidRequest("Material to be analyzed is missing. Please provide an array of strings.")
if len(data["material"]) < 1:
raise InvalidRequest("Material to be analyzed is missing, array is empty. Please provide an array of strings.")
真正有趣的部分是当我触发调试器来检查这里发生了什么。原来这条线
request.data['material']
在我的请求中给出列表的最后一个条目,在这种情况下
“Paska kesä taas. Kylmää ja sataa”
但是,当我检查 request.data 的内容时,它显示了一个查询字典,其中列出了请求中的管道和材料。为什么我在调用 request.data["material"] 时得到的是字符串而不是材料列表?有什么我忘记了,我必须指定某种序列化程序吗?为什么它在正常执行期间有效,但在测试时无效?
我将 Django 1.8 与 Python 3 结合使用。另外,我没有将视图绑定到任何特定模型。
最后,当我将断点放入视图时,调试器显示的内容如下: 请求数据:
QueryDict: {'material': ['Rakastan iloisuutta!', 'Autojen kanssa pitää olla varovainen.', 'Paska kesä taas. Kylmää ja sataa'], 'pipeline': ['Bayes']}
asd = request.data["material"]:
'Paska kesä taas. Kylmää ja sataa'
【问题讨论】:
-
Pipeline.execute_pipeline 有什么作用?
-
它处理材料。但是,我很确定问题出在此之前,因为调试器向我展示了 execute_pipeline 在测试期间实际上获取的是字符串而不是列表(它应该获取)。另外,如果我做了一个像 asd = request.data["material"] 这样的表达式,根据调试器 asd 包含列表的最后一个条目(字符串)。
-
如果手动测试它不会得到它?当这两个示例(打印)行位于彼此下方时,调试器输出会显示什么?
标签: python django django-rest-framework