AssertionError: 302 != 200 : Не удалось получить страницу перенаправления '/api/v2/app/nextdialog': код ответа был 302 (ожидалось 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
Пояснение кода: Приложение получает json полезную нагрузку в ConversationLayerView. Оно вызывает метод конечной точки, чтобы узнать, на какую конечную точку перенаправлять, основываясь на значении ключа '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", представление перенаправляется на "app-next-dialog" в представлении NextDialog. В этом представлении выполняется 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)
Если ключ присутствует, то перенаправьте на "response", чей вывод "/api/v2/app/reports?report_id=/reports/17340f51604cb35bd2c6b7b9b16f3aec", иначе не перенаправляйте, а верните 200.
Ошибка:
AssertionError: 302 != 200 : Couldn't retrieve redirection page '/api/v2/app/nextdialog': response code was 302 (expected 200)
Url.py
path(
"api/v2/ada/assessments",
views.PresentationLayerView.as_view(),
name="ada-assessments",
),
),
path("api/v2/ada/nextdialog", views.NextDialog.as_view(), name="ada-next-dialog"),
path("api/v2/ada/reports", views.Reports.as_view(), name="ada-reports"),
Пока что это не работает. В общем, я просто пытаюсь начать с вида 1, перенаправить на вид 2 и перенаправить на вид 3 с вида 2. Возможно ли это в Django? Спасибо.
Проблема скорее в ваших тестах, чем в логике представления - вполне возможно иметь цепочку перенаправлений.
assertRedirects
проверяет статус ответа, и по умолчанию требует, чтобы это был ответ HTTP 200. Поскольку у вас есть цепочка перенаправлений, ответом является 302 (еще одно перенаправление), а не 200, поэтому тест проваливается с ошибкой "response code was 302 (expected 200)".
Вам необходимо изменить аргумент target_status_code
, чтобы сообщить assertRedirects
, что вы ожидаете от ответа код состояния 302:
self.assertRedirects(response, self.destination_url, target_status_code=302)