djangoからAPIで他のサービスを呼び出してみます。この例ではOpenWeatherMapを使って任意の都市の天気予報を取得してみます
#1. Django環境を用意します
- Django Girls Tutorial、Djangoを使ってみる等を参照し、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,jp
、New York,us
など)で入力し、「問い合わせ」ボタンでリクエストを送付します
参考
- DjangoのREST化について - Django REST Frameworkを使って爆速でAPIを実装する