はじめに
Vue.js+Django REST frameworkを試す前段階として、まずDjango REST frameworkでAPIを実装します。
開発環境
$ python --version
Python 3.5.1
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.2
BuildVersion: 18C54
プロジェクトの作成
Djangoのプロジェクトを作成します。
# Djagoをインストール
pip install django
# プロジェクトを作成
django-admin startproject myproject
cd myproject
# 起動
python manage.py runserver
myproject
|_ myproject
|_ manage.py
|_ db.sqlite3
http://localhost:8000/ で画面が表示されているを確認します。
Django REST framework
設定
まずはDjango REST frameworkをインストールします。
pip install django-rest-framework
先程作ったプロジェクトのsettings.pyにrest_frameworkを追加します。
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]
...
次にAPIのエンドポイントを設定します。
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from rest_framework import routers
router = routers.DefaultRouter()
urlpatterns = [
path('admin/', admin.site.urls),
url('api/', include(router.urls)),
]
ここでDjango REST frameworkが正しく機能しているか確認します。
http://localhost:8000/api で以下の画面が実行されればOKです。
アプリケーションの追加
以下のdjango-adminのコマンドを使用してアプリケーションを作ります。
django-admin startapp myapp
myproject
|_ myproject
|_ __init__.py
|_ settings.py
|_ urls.py
|_ wsgi.py
|_ myapp
|_ migrations
|_ __init__.py
|_ admin.py
|_ apps.py
|_ models.py
|_ tests.py
|_ views.py
|_ manage.py
|_ db.sqlite3
アプリケーションをsettings.pyに追加します。
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'myapp',
]
...
ここからはガリガリAPIを実装していきます。
Models
from django.db import models
class Spot(models.Model):
# 名前
name = models.CharField(max_length=50)
# カテゴリー
category = models.CharField(max_length=5, blank=True)
# ジャンル
genre = models.CharField(max_length=50, blank=True)
# 都道府県
address_prefecture = models.CharField(max_length=10, blank=True)
# 市区町村
address_city = models.CharField(max_length=10, blank=True)
# 丁目番地等
address_street = models.CharField(max_length=100, blank=True)
# 緯度
latitude = models.CharField(max_length=50, blank=True)
# 経度
longitude = models.CharField(max_length=50, blank=True)
# 作成日
created_at = models.DateTimeField(auto_now_add=True)
# 更新日
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('created_at',)
以下のコマンドでマイグレーションします。(DBはとりあえずデフォルトのSQLiteのまま)
python manage.py makemigrations
python manage.py migrate
Serializers
from rest_framework import serializers
from .models import Spot
class SpotListSerializer(serializers.ModelSerializer):
# 名前
name = serializers.CharField(max_length=50)
# カテゴリー
category = serializers.CharField(max_length=5, allow_blank=True)
# 都道府県
address_prefecture = serializers.CharField(max_length=10, allow_blank=True)
class Meta:
model = Spot
fields = ('id', 'name', 'category', 'address_prefecture')
class SpotSerializer(serializers.ModelSerializer):
# 名前
name = serializers.CharField(max_length=50)
# カテゴリー
category = serializers.CharField(max_length=5, allow_blank=True)
# ジャンル
genre = serializers.CharField(max_length=50, allow_blank=True)
# 都道府県
address_prefecture = serializers.CharField(max_length=10, allow_blank=True)
# 市区町村
address_city = serializers.CharField(max_length=10, allow_blank=True)
# 丁目番地等
address_street = serializers.CharField(max_length=100, allow_blank=True)
# 緯度
latitude = serializers.CharField(max_length=50, allow_blank=True)
# 経度
longitude = serializers.CharField(max_length=50, allow_blank=True)
class Meta:
model = Spot
fields = (
'name', 'category', 'genre', 'address_prefecture', 'address_city', 'address_street', 'latitude',
'longitude')
Renderer
Jsonとして取得したいので、その処理をrenderers.pyとしてまとめます。
import json
from rest_framework.renderers import JSONRenderer
class SpotJSONRenderer(JSONRenderer):
charset = 'utf-8'
def render(self, data, accepted_media_type=None, renderer_context=None):
return json.dumps({
'spots': data
})
Views
from rest_framework import status
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from .models import Spot
from .renderers import SpotJSONRenderer
from .serializers import SpotListSerializer, SpotSerializer
class SpotListApiView(ListAPIView):
model = Spot
queryset = Spot.objects.all()
permission_classes = (AllowAny, )
renderer_classes = (SpotJSONRenderer, )
serializer_class = SpotListSerializer
class SpotRetrieveApiView(RetrieveAPIView):
permission_classes = (AllowAny, )
renderer_classes = (SpotJSONRenderer, )
serializer_class = SpotSerializer
def retrieve(self, request, spot_id, *args, **kwargs):
spot = Spot.objects.get(id=spot_id)
serializer = self.serializer_class(spot)
return Response(serializer.data, status=status.HTTP_200_OK)
Urls
apiのエンドポイントを定義します。
from django.conf.urls import url
from .views import SpotListApiView, SpotRetrieveApiView
app_name = 'myapp'
urlpatterns = [
url(r'^spots/$', SpotListApiView.as_view()),
url(r'^spots/(?P<spot_id>\w+)/?$', SpotRetrieveApiView.as_view()),
]
myprojectのurls.pyを更新します。
from django.conf.urls import include, url
from django.contrib import admin
from django.urls import path
from rest_framework import routers
from spot import urls
router = routers.DefaultRouter()
urlpatterns = [
path('admin/', admin.site.urls),
url('api/', include(router.urls)),
url('api/', include(urls, namespace='spot')),
]
ここまでの実装を確認するために、データをとりあえず追加します。
pip install ipyhton
python manage.py shell
In [1]: from myapp.models import Spot
In [2]: Spot.objects.create(name="秋葉原UDX", category="オフィス", genre="" , address_prefecture="東京都", address_city="千代田区", address_street="外神田4丁目14-1", latitude="35.700689", longitude="139.772498")
Out[2]: <Spot: Spot object (1)>
In [3]: Spot.objects.create(name="東京タワー", category="観光地", genre="" , address_prefecture="東京都", address_city="港区", address_street="芝公園4丁目2-8", latitude="35.658816", longitude="139.745476")
Out[3]: <Spot: Spot object (2)>
In [4]: Spot.objects.create(name="東京スカイツリー", category="観光地", genre="" , address_prefecture="東京都", address_city="墨田区", address_street="押上1丁目1-2", latitude="35.710385", longitude="139.810743")
Out[4]: <Spot: Spot object (3)>
In [5]: quit()
ブラウザで http://localhost:8000/api/spots/2 を開くと結果が確認できます。
終わりに
とりあえずGETだけでしたが、簡単にAPIを実装できたと思います。
みんなDjangoでAPIを実装すべし!
参考資料
Django REST framework
Cute cats web app Django + VueJs— Create a REST API with DRF