AssertionError: 302 != 200 : Couldn't retrieve redirection page '/api/v2/app/nextdialog': response code was 302 (expected 200)
AssertionError: 302 != 200 : Couldn't retrieve redirection page '/api/v2/app/nextdialog': response code was 302 (expected 200)
AssertionError: 302 != 200: 无法检索重定向页面“/api/v2/app/nextdialog”:响应代码为 302(预期为 200)
在 Django 中可以有三个视图,每个视图都重定向到下一个。视图 1 重定向到视图 2,视图 2 重定向到视图 3?
Views.py:
class ConversationLayerView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, *args, **kwargs):
body = request.data
cardType = body["cardType"]
if cardType == "CHOICE":
serializer = appChoiceTypeSerializer(body)
elif cardType == "TEXT":
serializer = appTextTypeSerializer(body)
elif cardType == "INPUT":
serializer = appInputTypeSerializer(body)
else:
serializer = StartAssessmentSerializer(body)
validated_body = serializer.validate_value(body)
url = get_endpoint(validated_body)
reverse_url = encodeurl(body, url)
return HttpResponseRedirect(reverse_url)
class NextDialog(generics.GenericAPIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, *args, **kwargs):
result = request.GET
data = result.dict()
contact_uuid = data["contact_uuid"]
step = data["step"]
value = data["value"]
description = data["description"]
title = data["title"]
if data["cardType"] == "CHOICE":
optionId = int(value) - 1
else:
optionId = data["optionId"]
path = get_path(data)
assessment_id = path.split("/")[-3]
request = build_rp_request(data)
app_response = post_to_app(request, path)
if data["cardType"] != "TEXT":
if data["cardType"] == "INPUT":
optionId = None
store_url_entry = appAssessments(
contact_id=contact_uuid,
assessment_id=assessment_id,
title=title,
description=description,
step=step,
user_input=value,
optionId=optionId,
)
store_url_entry.save()
pdf = pdf_ready(app_response)
if pdf:
response = pdf_endpoint(app_response)
return HttpResponseRedirect(response)
else:
message = format_message(app_response)
return Response(message, status=status.HTTP_200_OK)
class Reports(generics.GenericAPIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, *args, **kwargs):
report_id = request.GET.get("report_id")
response = get_report(report_id)
return Response(response, status=status.HTTP_200_OK)
Utils.py
def get_endpoint(payload):
value = payload["value"]
if value != "":
if value == "back":
url = reverse("app-previous-dialog")
elif value == "abort":
url = reverse("app-abort")
else:
url = reverse("app-next-dialog")
elif value == "":
url = reverse("app-start-assessment")
return url
def encodeurl(payload, url):
qs = "?" + urlencode(payload, safe="")
reverse_url = url + qs
return reverse_url
代码解释:
该应用程序在 ConversationLayerView 中接收 json 负载。它调用端点方法以根据有效负载中设置的 'value' 键知道要重定向到哪个端点。
请求看起来像这样:
{
"contact_uuid": "67460e74-02e3-11e8-b443-00163e990bdb",
"choices": null,
"value": "Charles",
"cardType": "INPUT",
"step": null,
"optionId": null,
"path": "",
"title": "",
"description": "What's your name",
"message": ""
}
由于“value”是“Charles”,视图重定向到 NextDialog 视图中的“app-next-dialog”。
在此视图中,向外部应用程序发出 POST 请求并收到 json 响应。如果响应具有 PDF 键,则此视图将重定向到第三个视图。
这发生在这里:
if pdf:
response = pdf_endpoint(app_response)
return HttpResponseRedirect(response)
else:
message = format_message(app_response)
return Response(message, status=status.HTTP_200_OK)
如果密钥存在,则重定向到输出为“/api/v2/app/reports?report_id=/reports/17340f51604cb35bd2c6b7b9b16f3aec”的“response”,否则不重定向,而是 return 200 .
错误:
AssertionError: 302 != 200 : Couldn't retrieve redirection page '/api/v2/app/nextdialog': response code was 302 (expected 200)
Url.py
path(
"api/v2/app/assessments",
views.PresentationLayerView.as_view(),
name="app-assessments",
),
path("api/v2/app/nextdialog", views.NextDialog.as_view(), name="app-next-dialog"),
path("api/v2/app/reports", views.Reports.as_view(), name="app-reports"),
test_views.py:
class appAssessmentReport(APITestCase):
data = {
"contact_uuid": "67460e74-02e3-11e8-b443-00163e990bdd",
"choices": None,
"message": (
"How old are you?\n\nReply *back* to go to "
"the previous question or *abort* to "
"end the assessment"
),
"explanations": "",
"step": 39,
"value": "27",
"optionId": None,
"path": "/assessments/f9d4be32-78fa-48e0-b9a3-e12e305e73ce/dialog/next",
"cardType": "INPUT",
"title": "Patient Information",
"description": "How old are you?",
}
start_url = reverse("app-assessments")
next_dialog_url = reverse("app-next-dialog")
pdf_url = reverse("app-reports")
destination_url = (
"/api/v2/app/nextdialog?contact_uuid="
"67460e74-02e3-11e8-b443-00163e990bdd&"
"choices=None&message=How+old+are+you%3F"
"%0A%0AReply+%2Aback%2A+to+go+to+the+"
"previous+question+or+%2Aabort%2A+to+end"
"+the+assessment&explanations=&step="
"39&value=27&optionId=None&path=%2F"
"assessments%2Ff9d4be32-78fa-48e0-b9a3"
"-e12e305e73ce%2Fdialog%2Fnext&cardType"
"=INPUT&title=Patient+Information&"
"description=How+old+are+you%3F"
)
@patch("app.views.pdf_ready")
@patch("app.views.post_to_app")
def test_assessment_report(self, mock_post_to_app, mock_pdf_ready):
mock_post_to_app.return_value = {
"cardType": "CHOICE",
"step": 40,
"title": {"en-US": "YOUR REPORT"},
"description": {"en-US": ""},
"options": [
{"optionId": 0, "text": {"en-US": "Option 1"}},
{"optionId": 1, "text": {"en-US": "Option 2"}},
{"optionId": 2, "text": {"en-US": "Option 3"}},
],
"_links": {
"self": {
"method": "GET",
"href": "/assessments/898d915e-229f-48f2-9b98-cfd760ba8965",
},
"report": {
"method": "GET",
"href": "/reports/17340f51604cb35bd2c6b7b9b16f3aec",
},
},
}
mock_pdf_ready.return_value = utils.pdf_ready(mock_post_to_app.return_value)
user = get_user_model().objects.create_user("test")
self.client.force_authenticate(user)
response = self.client.post(self.start_url, self.data, format="json")
print(response)
self.assertRedirects(response, self.destination_url)
到目前为止这不起作用。总之,我只是想从视图 1 开始,重定向到视图 2,然后从视图 2 重定向到视图 3。
这在 Django 中可能吗?
谢谢。
问题出在你的测试上,而不是出在视图逻辑上——完全有可能有一个重定向链。
assertRedirects
检查响应的状态,默认情况下要求它是 HTTP 200 响应。因为你有一个重定向链,响应是 302(另一个重定向)而不是 200,这就是为什么测试失败并显示错误“响应代码是 302(预期 200)”。
您需要修改 target_status_code
参数以告知 assertRedirects
您期望响应具有 302 状态代码:
self.assertRedirects(response, self.destination_url, target_status_code=302)
AssertionError: 302 != 200: 无法检索重定向页面“/api/v2/app/nextdialog”:响应代码为 302(预期为 200)
在 Django 中可以有三个视图,每个视图都重定向到下一个。视图 1 重定向到视图 2,视图 2 重定向到视图 3?
Views.py:
class ConversationLayerView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, *args, **kwargs):
body = request.data
cardType = body["cardType"]
if cardType == "CHOICE":
serializer = appChoiceTypeSerializer(body)
elif cardType == "TEXT":
serializer = appTextTypeSerializer(body)
elif cardType == "INPUT":
serializer = appInputTypeSerializer(body)
else:
serializer = StartAssessmentSerializer(body)
validated_body = serializer.validate_value(body)
url = get_endpoint(validated_body)
reverse_url = encodeurl(body, url)
return HttpResponseRedirect(reverse_url)
class NextDialog(generics.GenericAPIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, *args, **kwargs):
result = request.GET
data = result.dict()
contact_uuid = data["contact_uuid"]
step = data["step"]
value = data["value"]
description = data["description"]
title = data["title"]
if data["cardType"] == "CHOICE":
optionId = int(value) - 1
else:
optionId = data["optionId"]
path = get_path(data)
assessment_id = path.split("/")[-3]
request = build_rp_request(data)
app_response = post_to_app(request, path)
if data["cardType"] != "TEXT":
if data["cardType"] == "INPUT":
optionId = None
store_url_entry = appAssessments(
contact_id=contact_uuid,
assessment_id=assessment_id,
title=title,
description=description,
step=step,
user_input=value,
optionId=optionId,
)
store_url_entry.save()
pdf = pdf_ready(app_response)
if pdf:
response = pdf_endpoint(app_response)
return HttpResponseRedirect(response)
else:
message = format_message(app_response)
return Response(message, status=status.HTTP_200_OK)
class Reports(generics.GenericAPIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, *args, **kwargs):
report_id = request.GET.get("report_id")
response = get_report(report_id)
return Response(response, status=status.HTTP_200_OK)
Utils.py
def get_endpoint(payload):
value = payload["value"]
if value != "":
if value == "back":
url = reverse("app-previous-dialog")
elif value == "abort":
url = reverse("app-abort")
else:
url = reverse("app-next-dialog")
elif value == "":
url = reverse("app-start-assessment")
return url
def encodeurl(payload, url):
qs = "?" + urlencode(payload, safe="")
reverse_url = url + qs
return reverse_url
代码解释: 该应用程序在 ConversationLayerView 中接收 json 负载。它调用端点方法以根据有效负载中设置的 'value' 键知道要重定向到哪个端点。
请求看起来像这样:
{
"contact_uuid": "67460e74-02e3-11e8-b443-00163e990bdb",
"choices": null,
"value": "Charles",
"cardType": "INPUT",
"step": null,
"optionId": null,
"path": "",
"title": "",
"description": "What's your name",
"message": ""
}
由于“value”是“Charles”,视图重定向到 NextDialog 视图中的“app-next-dialog”。 在此视图中,向外部应用程序发出 POST 请求并收到 json 响应。如果响应具有 PDF 键,则此视图将重定向到第三个视图。 这发生在这里:
if pdf:
response = pdf_endpoint(app_response)
return HttpResponseRedirect(response)
else:
message = format_message(app_response)
return Response(message, status=status.HTTP_200_OK)
如果密钥存在,则重定向到输出为“/api/v2/app/reports?report_id=/reports/17340f51604cb35bd2c6b7b9b16f3aec”的“response”,否则不重定向,而是 return 200 .
错误:
AssertionError: 302 != 200 : Couldn't retrieve redirection page '/api/v2/app/nextdialog': response code was 302 (expected 200)
Url.py
path(
"api/v2/app/assessments",
views.PresentationLayerView.as_view(),
name="app-assessments",
),
path("api/v2/app/nextdialog", views.NextDialog.as_view(), name="app-next-dialog"),
path("api/v2/app/reports", views.Reports.as_view(), name="app-reports"),
test_views.py:
class appAssessmentReport(APITestCase):
data = {
"contact_uuid": "67460e74-02e3-11e8-b443-00163e990bdd",
"choices": None,
"message": (
"How old are you?\n\nReply *back* to go to "
"the previous question or *abort* to "
"end the assessment"
),
"explanations": "",
"step": 39,
"value": "27",
"optionId": None,
"path": "/assessments/f9d4be32-78fa-48e0-b9a3-e12e305e73ce/dialog/next",
"cardType": "INPUT",
"title": "Patient Information",
"description": "How old are you?",
}
start_url = reverse("app-assessments")
next_dialog_url = reverse("app-next-dialog")
pdf_url = reverse("app-reports")
destination_url = (
"/api/v2/app/nextdialog?contact_uuid="
"67460e74-02e3-11e8-b443-00163e990bdd&"
"choices=None&message=How+old+are+you%3F"
"%0A%0AReply+%2Aback%2A+to+go+to+the+"
"previous+question+or+%2Aabort%2A+to+end"
"+the+assessment&explanations=&step="
"39&value=27&optionId=None&path=%2F"
"assessments%2Ff9d4be32-78fa-48e0-b9a3"
"-e12e305e73ce%2Fdialog%2Fnext&cardType"
"=INPUT&title=Patient+Information&"
"description=How+old+are+you%3F"
)
@patch("app.views.pdf_ready")
@patch("app.views.post_to_app")
def test_assessment_report(self, mock_post_to_app, mock_pdf_ready):
mock_post_to_app.return_value = {
"cardType": "CHOICE",
"step": 40,
"title": {"en-US": "YOUR REPORT"},
"description": {"en-US": ""},
"options": [
{"optionId": 0, "text": {"en-US": "Option 1"}},
{"optionId": 1, "text": {"en-US": "Option 2"}},
{"optionId": 2, "text": {"en-US": "Option 3"}},
],
"_links": {
"self": {
"method": "GET",
"href": "/assessments/898d915e-229f-48f2-9b98-cfd760ba8965",
},
"report": {
"method": "GET",
"href": "/reports/17340f51604cb35bd2c6b7b9b16f3aec",
},
},
}
mock_pdf_ready.return_value = utils.pdf_ready(mock_post_to_app.return_value)
user = get_user_model().objects.create_user("test")
self.client.force_authenticate(user)
response = self.client.post(self.start_url, self.data, format="json")
print(response)
self.assertRedirects(response, self.destination_url)
到目前为止这不起作用。总之,我只是想从视图 1 开始,重定向到视图 2,然后从视图 2 重定向到视图 3。 这在 Django 中可能吗? 谢谢。
问题出在你的测试上,而不是出在视图逻辑上——完全有可能有一个重定向链。
assertRedirects
检查响应的状态,默认情况下要求它是 HTTP 200 响应。因为你有一个重定向链,响应是 302(另一个重定向)而不是 200,这就是为什么测试失败并显示错误“响应代码是 302(预期 200)”。
您需要修改 target_status_code
参数以告知 assertRedirects
您期望响应具有 302 状态代码:
self.assertRedirects(response, self.destination_url, target_status_code=302)