Как обрабатывать KeyError в ответе HTTP при получении данных (с использованием запросов Django) - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь сделать запросы API для извлечения данных из стороннего API, чтобы манипулировать / отображать данные в моей панели. Включая ответные данные, все работает хорошо, но кажется, что что-то не так со словарем / ключами в данных json api.

В частности, я хотел бы получить значения ключей 'name' и 'country', которые правильно выбираются через ответ http в соответствии с отладкой Django.

Я всегда получаю KeyError, как показано ниже.

Что мне здесь не хватает? (Я не уверен, что это важно, но мой линтер говорит мне, что json импортирован, но не используется в views.py)

Это ответ:

Variable    Value
request 
<WSGIRequest: GET '/dashboard/'>
response    
<Response [200]>
team_data   
{'api': {'ENDOINTS': {'countries': {'countries': 'https://www.api-football.com/demo/api/v2/countries'},
                      'events': {'events': 'https://www.api-football.com/demo/api/v2/events/{fixture_id}'},
                      'fixtures': {'date': 'https://www.api-football.com/demo/api/v2/fixtures/date/{date}',
                                   'h2h': 'https://www.api-football.com/demo/api/v2/fixtures/h2h/{team_1}/{team_2}',
                                   'id': 'https://www.api-football.com/demo/api/v2/fixtures/id/{fixture_id}',
                                   'league': 'https://www.api-football.com/demo/api/v2/fixtures/league/{league_id}',
                                   'live': 'https://www.api-football.com/demo/api/v2/fixtures/live',
                                   'team': 'https://www.api-football.com/demo/api/v2/fixtures/team/{team_id}'},
                      'leagues': {'country': 'https://www.api-football.com/demo/api/v2/leagues/country/{country_name}/{season}',
                                  'league': 'https://www.api-football.com/demo/api/v2/leagues/league/{league_id}',
                                  'leagues': 'https://www.api-football.com/demo/api/v2/leagues',
                                  'season': 'https://www.api-football.com/demo/api/v2/leagues/season/{season}'},
                      'lineups': {'lineups': 'https://www.api-football.com/demo/api/v2/lineups/{fixture_id}'},
                      'odds': {'bookmakers': 'https://www.api-football.com/demo/api/v2/odds/bookmakers/',
                               'fixture': 'https://www.api-football.com/demo/api/v2/odds/fixture/{fixture_id}',
                               'labels': 'https://www.api-football.com/demo/api/v2/odds/labels/',
                               'league': 'https://www.api-football.com/demo/api/v2/odds/league/{league_id}'},
                      'players': {'player': 'https://www.api-football.com/demo/api/v2/players/player/{player_id}',
                                  'seasons': 'https://www.api-football.com/demo/api/v2/players/seasons',
                                  'team': 'https://www.api-football.com/demo/api/v2/players/team/{team_id}'},
                      'seasons': {'seasons': 'https://www.api-football.com/demo/api/v2/seasons'},
                      'standings': {'leagueTable': 'https://www.api-football.com/demo/api/v2/leagueTable/{league_id}'},
                      'statistics': {'fixture': 'https://www.api-football.com/demo/api/v2/statistics/fixture/{fixture_id}',
                                     'team': 'https://www.api-football.com/demo/api/v2/statistics/{league_id}/{team_id}'},
                      'teams': {'league': 'https://www.api-football.com/demo/api/v2/teams/league/{league_id}',
                                'team': 'https://www.api-football.com/demo/api/v2/teams/team/{team_id}'},
                      'transfers': {'player': 'https://www.api-football.com/demo/api/v2/transfers/player/{player_id}',
                                    'team': 'https://www.api-football.com/demo/api/v2/transfers/team/{team_id}'}},
         'WARNING': 'THIS IS A DEMO AND DOES NOT REPRESENT THE ENTIRE API. THE '
                    'DATA IS LIMITED AND NOT UP TO DATE AND SERVES ONLY AS AN '
                    'EXAMPLE. FOR PRODUCTION ENVIRONEMENT USE : '
                    'HTTPS://API-FOOTBALL-V1.P.RAPIDAPI.COM/V2/',
         'results': 1,
         'teams': [{'code': None,
                    'country': 'Brazil',
                    'founded': 1909,
                    'logo': 'Not available in Demo',
                    'name': 'Internacional',
                    'team_id': 33,
                    'venue_address': 'Avenida Padre Cacique 891, Bairro Menino '
                                     'Deus',
                    'venue_capacity': 50128,
                    'venue_city': 'Porto Alegre, Rio Grande do Sul',
                    'venue_name': 'Estádio José Pinheiro Borda',
                    'venue_surface': 'grass'}]}}

Это моя функция просмотра:

import requests
from django.shortcuts import render
import json

def team_update(request):
    response = requests.get('http://www.api-football.com/demo/api/v2/teams/team/33')
    team_data = response.json()
    print(team_data)
    return render(request, 'index.html', {
        'name': team_data['name'],
        'country': team_data['country'],
    })

Это ошибка:

KeyError at /dashboard/
'name'
Request Method: GET
Request URL:    http://127.0.0.1:8000/dashboard/
Django Version: 2.2.5
Exception Type: KeyError
Exception Value:    
'name'
Exception Location: C:\Users\Jonas \Desktop\dasocc\dasocc_site\dasocc_app\views.py in team_update, line 25

Большое спасибо за вашевведите заранее.

- # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - #- # - # -

Обновление / Решение:

def team_update(request):
    response = requests.get('http://www.api-football.com/demo/api/v2/teams/team/33')
    team_data = response.json()
    teams = team_data.get('api', {}).get('teams', [])
    if teams and len(teams) == 1:
        teams = teams[0]
        context = {'name': teams['name'], 'country': teams['country']}
    return render(request, 'index.html', {
        'name': teams['name'],
        'country': teams['country'],
    })

1 Ответ

1 голос
/ 01 октября 2019

Способ безопасного доступа к вашей команде с помощью такого ответа - убедиться, что вы полностью не обращаетесь к ключам, которые могут не существовать, или к объектам в списке, которые могут не существовать. Поэтому не используйте ключи [key], а get(). Если API возвращает {'status': 'error', 'errors': {...}}, то ваш код все равно будет зависать, если вы просто предположите, что он имеет ключ «API»:

teams = team_data.get('api', {}).get('teams', [])
if isinstance(teams, list) and len(teams) == 1:
   team = teams[0]
   context = {'name': team['name'], 'country': team['country']} # might also crash if for some reason the api returns a team without country, but not likely
else:
   # handle the issue teams is empty or there's more than 1 team or teams isn't what was expected
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...