【Django】DjangoRESTFramework のチュートリアルをやってみる : QuickStart偏

# Django REST Framework のクイックスタート

なんのひねりもなく[公式チュートリアル](https://www.django-rest-framework.org/tutorial/quickstart/)をやるだけ

## project 作成

```
# ディレクトリ作成
$ mkdir drf && cd drf

# 仮想環境作成
$ python -m venv drf
$ source drf/bin/activate

# django , django rest framework をインストール
$ pip install --upgrade pip
$ pip install django
$ pip install djangorestframework

# プロジェクト、アプリを作成
$ django-admin startproject tutorial
$ cd tutorial
$ django-admin startapp quickstart

# migrate, スーパーユーザ作成
$ python manage.py migrate
$ python manage.py createsuperuser --email admin@example.com --username admin
```

ユーザ作成まで完成したら、コードを作っていく

## API作成

### Serializer

quickstart appにて`serializers.py`というファイルを作成する
中身は以下の通り

```py:tutorial/quickstart/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']
```

serializer というものが何なのか正直今のところよくわかっていない
    →Serializer偏で判明
また、RESTfulのAPIにはHyperlinkingのデータリレーションが良いので、
serializerにHyperlinkedリレーションを作成しているという記述があるが、
これも正直意味が分からんので、とりあえず従う


### View

views.py は以下の通り

```py:/tutorial/quickstart/views.py
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from quickstart.serializers import UserSerializer, GroupSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]

class GroupViewSet(viewsets.ModelViewSet):
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]
```

ViewSetクラスは、ユーザに読み書き権限を与えるAPIエンドポイントの模様
ViewSetクラスを利用すると、似たような機能を集約できるらしい
ViewSetクラスは簡単に分解して複数のViewで書けるけど、ViewSetを使うことでいい感じに機能が集約できるらしい
大事なことなので2回言いました
正直似たような機能ってつまりどういうことか今の段階では全然わからん
とりあえずここで指定しているのは、このAPIを利用するユーザに対して、読み書き権限をそれぞれどうするかというものなのだと思う


### URL

viewの代わりにViewSetを使うことで、API用のURL設定を自動で生成することができるらしい
自動生成にはviewsetsをrouterクラスに登録するだけでOK

シンプルなViewを使った場合、詳細設定ができる余地がある

url.py は以下の通り

```py:/tutorial/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from quickstart import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
```

router = routers.DefaultRouter() : おそらく初期化
router.register(~~) : router に route を登録しているのだと思う

`/` : router の urls を参照
`api-auth/` : rest_framework の urls を参照


## Pagination

`Pagination`を設定することで、1ページ当たりどれくらいのオブジェクトを制御できるかを指定できる
`settings.py`に記述することで可能らしい

Paginationを設定する意味は今のところわからん

```py
# Pagination(setting.py 最下部に追記)
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}
```

## Settings.py に rest_framework を追加

`INSTALLED_APP`に`rest_framework`を追加することで利用できるようにする

```py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]
```

## APIの確認

ここまでくるとアプリを起動可能のはずなので、APIをテストしてみる

```
$ python manage.py runserver
```

サーバが起動できたら、もう一つターミナルを開いて、↓実行
※[password]は自身が設定したものに変更

```
$ curl -H 'Accept: application/json; indent=4' -u admin:[password] 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": []
        }
    ]
}
```

JSONデータが返ってきた！

- ブラウザにアクセスでもOK
  - アドレスバーに/users/1 とか入力したらページ表示される
  - ログインしてないと403 forbiddenが表示されるが、右上にログインボタンがある

# おわり

これにてDjango REST Frameworkの力でURLを叩くとDBに保存されたモデルのデータがJSONで返ってくるAPIを作ることができた
この後やることは、
このJSONデータをどのようにして整形してフロントで反映させるかをReact(Next.js)で実装していくか、
になっていく、、、