django rest frameworkについては公式のquick startを参考にする。
ほぼ、上記のquick startのコピペ。ディレクトリ名などは変えている。
環境
- python3.8.2
主なパッケージ
- django
- djangorestframework
プロジェクト作成
# まずpythonの環境を整える(venvの環境を作った場合の例)
source path/to/venv/bin/activate
# プロジェクト作成
django-admin startproject ml_web
app作成
cd ml_web
python manage.py startapp web_tool
初期マイグレーションとDBの初期ユーザー作成
python manage.py migrate
python manage.py createsuperuser --email admin@example.com --username admin
# --> パスワード聞かれるから設定する
モデルのシリアライザを作る
ml_web/web_tool/serializers.py
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url', 'username', 'email', 'groups']
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ['url', 'name']
シリアライザーはHyperlinkedModelSerializer
以外にも色々あるらしいがこれが良いRESTfullデザインとのこと。
シリアライザーについての詳細(公式):https://www.django-rest-framework.org/api-guide/serializers/
チュートリアル(公式):https://www.django-rest-framework.org/tutorial/1-serialization/
ビュー
各モデル単一のビューではなく、ビューセットとしている。
ml_web/web_tool/views.py
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets
from web_tool.serializers import GroupSerializer, UserSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [permissions.IsAuthenticated]
ルーティング設定
ビューセット単位でURLを設定。
ml_web/urls.py
from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from web_tool import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/',
include('rest_framework.urls', namespace='rest_framework'))
]
Settings
プロジェクトルート/ml_web/settings.py
INSTALLED_APPS
に以下を追加。
INSTALLED_APPS = [
...
'web_tool',
'rest_framework',
]
REST_FRAMEWORK
を設定することでページネーション設定が簡単にできる。
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':
'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
APIを試す
プロジェクト直下(manage.pyがあるディレクトリ)で、
python manage.py runserver
で、 http://127.0.0.1:8000/にアクセスするとbrowsable apiで自動生成されるページが表示されるはず。以下のように。
あるいは、以下のようなcurlを叩く。
# ID/passは適宜
curl -H 'Accept: application/json; indent=4' -u admin:admin123 http://127.0.0.1:8000/users/
以下のようなレスポンスが返ってくる
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "http://127.0.0.1:8000/users/1/",
"username": "admin",
"email": "admin@example.com",
"groups": []
}
]
}
この時点でのディレクトリ構成(__pychache__
は省いて表示している)は以下。ルートディレクトリのml_web
直下でtree
で可視化した結果。
.
├── db.sqlite3
├── design
│ └── overview.puml
├── manage.py
├── ml_web
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── web_tool
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ ├── __init__.py
├── models.py
├── serializers.py
├── tests.py
└── views.py