26
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoでAPI呼び出し

Last updated at Posted at 2018-05-07

djangoからAPIで他のサービスを呼び出してみます。この例ではOpenWeatherMapを使って任意の都市の天気予報を取得してみます

#1. Django環境を用意します

#2. アプリを用意します

  • python manage.py startapp アプリ名でアプリを用意します。ここではサンプルとしてrestというアプリを作成しています
  • 上記で作成したアプリをプロジェクト名/urls.pyに登録します
project/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('rest/', include('rest.urls')),    
]

  • アプリ名/urls.pyに作成する画面に応じてアプリ名/urls.pyに登録します。ここではアプリの初期画面(rest/)としてindex.htmlを表示し、そこから送付した問い合わせに応じてrest/forecastというパスでforecast.htmlが表示されることにします
app/urls.py
urlpatterns = [
    path('', views.rest, name='rest'),
    path('forecast', views.forecast, name='forecast'),    
]

#3. viewsにAPI呼び出しメソッドを記述します
-OpenWeatherMapへサインアップ(無料)して32桁のAPIキーを取得します

views.py

from django.shortcuts import render
import requests

def rest(request):
    print("rest entered")
    return render(request, 'rest/index.html')

def forecast(request):
    print("forecast entered")
    API_Key = '32桁のOpenWeatherMapのAPIキーを入力'
    city = "Tokyo,jp"
    if request.POST['city']:
        city = request.POST['city']
    url = 'http://api.openweathermap.org/data/2.5/forecast'
    query = {
        'units': 'metric',
        'q': city,
        'cnt': '30',
        'appid': API_Key
    }
    r = requests.get(url, params=query)
    print("response", r.json())
    print("Weather forecast in Tokyo at UTC(needs +9h): ")
    result = []
    for x in range(r.json()['cnt']):
        print("x: ", x)
        result.append(r.json()['list'][x]['dt_txt'])
        result.append("temp: ")
        result.append(r.json()['list'][x]['main']['temp'])
        result.append("weather: ")
        result.append(r.json()['list'][x]['weather'][0]['main'])
        result.append("/")
        result.append(r.json()['list'][x]['weather'][0]['description'])
        result.append('\n')

        print(r.json()['list'][x]['dt_txt'],
        "temp: ", r.json()['list'][x]['main']['temp'],
        "weather: ", r.json()['list'][x]['weather'][0]['main'], "/", r.json()['list'][x]['weather'][0]['description'])

    mapped_num = map(str, result) #格納される数値を文字列にする
    result_string = ' '.join(mapped_num)
    print("result_string", result_string)
    print("city", city)
    return render(request, 'rest/forecast.html', {'city': city, 'result': result_string})

#4. templateを用意します

  • 上記画面遷移に応じたhtmlファイルを用意します
base.html
{% load static %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static 'vendor/bootstrap/css/bootstrap-grid.min.css' %}" rel="stylesheet">
<script src="{% static 'vendor/jquery/jquery-3.2.1.min.js' %}"></script>
<script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>
<link href="{% static 'app/search/search.css' %}" rel="stylesheet">
{% block extrahead %}{% endblock %}
</head>
<body>
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark" style="margin-bottom: 1rem;">
    <a class="navbar-brand" href="/">Django Exercise</a>
    <div class="collapse navbar-collapse" id="navbarNav">
    </div>
  </nav>

  <div class="container">
    {% block content %}
      {{ content }}
    {% endblock %}
  </div>
</body>
</html>
index.html
{% extends "rest/base.html" %}

{% block title %}REST Exercise{% endblock title %}

{% block content %}

<div class="row">
  <div class="col-sm-12 col-md-12">
    <div class="card">
      <div class="card-header">Target</div>
      <div class="card-body">
        <form action="{% url 'forecast' %}" method="POST" enctype="multipart/form-data">
          {% csrf_token %}
          <div class="form-group row">
            <label for="model" class="col-sm-1 col-form-label">City</label>
            <div class="col-sm-3">
              <input type="text" class="form-control sbc_field" name="city" placeholder="Tokyo,jp"/>
            </div>
            <button type="submit" class="btn btn-primary" name='action' value="save">問い合わせ</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

{% endblock %}
forecast.html
{% extends "rest/base.html" %}

{% block title %}REST Exercise{% endblock title %}

{% block content %}

<div class="row">
  <div class="col-sm-12 col-md-12">
    <div class="card">
      <div class="card-header">Target</div>
      <div class="card-body">
        <form action="{% url 'forecast' %}" method="POST" enctype="multipart/form-data">
          {% csrf_token %}
          <div class="form-group row">
            <label for="model" class="col-sm-1 col-form-label">City</label>
            <div class="col-sm-3">
              <input type="text" class="form-control sbc_field" name="city" placeholder="Tokyo,jp"/>
            </div>
            <button type="submit" class="btn btn-primary" name='action' value="save">問い合わせ</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

<div class="row">
  <div class="col-sm-12 col-md-12">
    <div class="card">
      <div class="row">
        <div class="col-sm-12 col-md-12">
          <div class="card">
            <div>
              <h2>{{ city }} の天気</h2>
            <p>{{ result|linebreaksbr  }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

{% endblock %}

#5. 稼働確認します

  • http://localhost:8000/restで初期画面へアクセスし、天気予報を知りたい都市名を都市名,国名(例:Tokyo,jpNew York,usなど)で入力し、「問い合わせ」ボタンでリクエストを送付します
スクリーンショット 2018-05-08 8.21.03.png スクリーンショット 2018-05-08 8.21.23.png

参考

26
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?