Django ModelViewSetの使い方

#ModelViewSetとは
モデルに対する、`一覧取得`、`詳細取得`、`新規作成`、`更新`、`削除`を
一括で作成してくれます😃

`ReadOnlyModelViewSet`を継承すれば、一覧取得と詳細取得だけにできる😃😃

#基本的な使い方

###書き方

使い方の注意は、`urls.py`にパス追加する方法が、`APIView`などとは少し違うということ!

```python:book/views.py

from rest_framework import generics, viewsets

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()

```

```python:book/urls.py
from rest_framework import routers

router = routers.DefaultRouter()
router.register('books', BookViewSet)

```

###確認する

```bash:terminal

curl http://127.0.0.1:8000/api/v1/book/books/
[{"id":"a088ae31-dbe4-4435-8dc9-356378b6def9","is_deleted":"0","created_at: ...."}]

curl http://127.0.0.1:8000/api/v1/book/books/<pkをいれる>/
{"id":"a088ae31-dbe4-4435-8dc9-356378b6def9","is_deleted":"0"," ....."}

curl -XPOST http://127.0.0.1:8000/api/v1/book/books/ -d "title=test&sub_titl..."
{"id":"fc21044e-7388-4391-b498-8b472350282f","is_deleted":"0"...}

curl -XPATCH  http://127.0.0.1:8000/api/v1/book/books/<pk>/ -d 'is_deleted=1'
{"id":"a088ae31-dbe4-4435-8dc9-356378b6def9","is_deleted":"1"," ....."}

curl -XDELETE  http://127.0.0.1:8000/api/v1/book/books/<pk>/

```

無事にできました😃

#カスタマイズする
###actionデコレータ
これは絶対に覚えておきたいと思うので最初に書きます!
urlに追加してくれて、機能を追加してくれます☺️

<b> 例: <b/>

```python:views.py

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()

    @action(detail=True, methods=['get'])
    def authors(self, request, pk=None):
        author = Author.objects.all()
        serializer = AuthorSerializer(author, many=True)
        return Response(serializer.data)

```
このように書きます! 


もちろん、こんな感じの機能は追加することはないでしょうが笑
ということでAPIを確認します!😃

```bash:terminal

curl http://127.0.0.1:8000/api/v1/book/books/1/authors/
[{"id":"a739d3f5-a170-4472-a7af-33a44f8f5512","is_deleted":"0"...}]

```
`detail`とは、一覧APIなのか詳細APIなのかを判断しています。(Trueだと詳細)
一覧APIの場合は、引数の`pk`は入りません。!

`methods`とは、HTTPメソッドを定義しています。(`get`, `post`, `put`, `patch`,`delete`)
※複数も可能`methods=['get', 'patch']`

###認証の設定
`APIView`などのように認証の設定も可能です

```python:views.py
class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()
    authentication_classes = [IsAccountAdminOrReadOnly]
```

actionデコレータでも可能!

```python:views.py
@action(detail=True, methods=['post'], permission_classes=[IsAccountAdminOrReadOnly])
```

###フィルターの設定

rest_frameworkのfiltersを使ってみる😃

```python:views.py

from rest_framework import filters

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()
    filter_backends = [filters.SearchFilter]
    search_fields = ['sub_title','title']
```

確認する!
`?serach=検索文字列`で検索できる☺️

```bash:terminal
curl http://127.0.0.1:8000/api/v1/book/books/?search=設計・運用計画の鉄則

[{"id":"a088ae31-dbe4-4435-8dc9-356378b6def9","is_deleted":"0" ... ,"sub_title":"設計・運用計画の鉄則" ...}]

```

無事に取得できました😃😃😃

###使わないHTTPメソッドを省く

ViewSetを使うと、DELETEとか使わないのにあるからデータ消されちゃう😭😭😭😭
その対策は、継承を変更すれば大丈夫!!!

```python:views.py

from rest_framework import mixins

class AuthorViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
```
この場合は作成と一覧のみ!!

`mixins.CreateModelMixin
mixins.RetrieveModelMixin
mixins.UpdateModelMixin
mixins.DestroyModelMixin
mixins.ListModelMixin`

使うものを継承する😃😃😃😃😃😃

以上!!!
お疲れ様です!!😃😃

[公式サイトはこちらです!!!!!](https://www.django-rest-framework.org/api-guide/viewsets/)