#python #json #django #django-rest-framework #python-requests
#python #json #django #django-rest-framework #python-запросы
Вопрос:
Я создаю интерфейс RESTful для проекта Django, и мне нужно использовать внешние API, чтобы клиент и интерфейс могли ссылаться только на один API Django, не требуя подробностей о внешних API.
Поэтому я хочу, чтобы данные внешнего API возвращались на страницы API, доступные для просмотра, так же, как я бы использовал свой собственный API на основе представления.
Как мне сериализовать ответ JSON из внешнего API в средство визуализации веб-страницы с возможностью просмотра API?
Например, я хочу, чтобы mysite.fake/thing/details возвращал тот же JSON, который возвращается externalapi.fake/thing/details , который выглядит как:
{"thing_id": "900404", "description": "Thing description", "value": "100.00", "location": "Bin 401"}
И это должно отображаться в доступном для просмотра API для DRF.
В настоящее время я использую:
@api_view(('GET',))
@renderer_classes((JSONRenderer,))
def thing_finder(request, thing_id):
"""
Get the current location for a thing
http://localhost:8000/thing/find/9900404
:param request: HTTP Request object
:param thing_id: String - the thing ID
:return: JSON - The Thing location JSON
"""
a, b = THING_API_AUTH
if request.method == 'GET':
payload = {'thing_id': thing_id}
r = requests.get(THING_API_AUTH, auth=HTTPBasicAuth(a, b), params=payload)
if r.status_code == 200:
data = json.loads(r.text)
serializer = ThingFinderSerializer(data)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response({"error": "Request failed"}, status=r.status_code)
В settings.py
я включаю:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
Это работает (я думаю), но не форматирует результаты в доступный для просмотра API. Вместо этого я получаю неформатированную страницу с выгруженным на нее JSON. Я пропустил требование к шаблону? Неправильный URL-адрес в браузере? BrowsableAPIRenderer
settings.py
Недостаточно ли для рендеринга по умолчанию для просматриваемого API? TIA.
Ответ №1:
Здесь вам не нужно использовать сериализатор в качестве внешнего источника, возвращающего данные JSON. Вы можете использовать response.json()
метод как
@api_view(('GET',))
@renderer_classes((JSONRenderer,))
def thing_finder(request, thing_id):
a, b = THING_API_AUTH
if request.method == 'GET':
payload = {
'thing_id': thing_id
}
response = requests.get(
THING_API_AUTH,
auth=HTTPBasicAuth(a, b),
params=payload
)
if response.status_code == 200:
return Response(response.json(), status=status.HTTP_200_OK)
return Response({"error": "Request failed"}, status=response.status_code)
Комментарии:
1. Я пытаюсь получить ответ для рендеринга в доступном для просмотра API DRF — если я использую ваш метод, я получаю ту же страницу без стиля, только с возвращением необработанного JSON. Но это хороший совет только для необработанного JSON.
2. Тогда какой формат вы ожидаете? покажите некоторый пример
3. Форматированный рендеринг, подобный этому: django-rest-framework.org/api-guide/renderers /…
4. Я не понимаю, в чем разница. Возможно, добавление скриншота или изображения может помочь (мне) понять ситуацию
5. Я решил это — мне нужно было включить декоратор BrowsableAPIRenderer вместе с JSONRenderer. Спасибо
Ответ №2:
Я решил это:
from rest_framework.renderers import JSONRenderer, BrowsableAPIRendererenter
@api_view(('GET',))
@renderer_classes((JSONRenderer, BrowsableAPIRenderer))
def thing_finder(request, thing_id):
"""
Get the current location for a thing
http://localhost:8000/thing/find/9900404
:param request: HTTP Request object
:param thing_id: String - the thing ID
:return: JSON - The Thing location JSON
"""
a, b = THING_API_AUTH
if request.method == 'GET':
payload = {'thing_id': thing_id}
r = requests.get(THING_API_AUTH, auth=HTTPBasicAuth(a, b), params=payload)
if r.status_code == 200:
data = json.loads(r.text)
serializer = ThingFinderSerializer(data)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response({"error": "Request failed"}, status=r.status_code)
Это возвращает доступную для просмотра визуализацию API в виде чистой, отформатированной страницы.