Django Rest Framework querysetつかうViewset、使わないViewset

# Django queryset使うやつと使わないViewSetを意識する

### querysetを使わない
**mixins.CreateModelMixin** 
```python
class CreateModelMixin:
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}
```

CreateModelMixinは挙動としてはSerializerを介すだけなので動作は非常に簡単です。
リクエストデータをviewの中で定義したserializerに突っ込んでシリアライズし、入力値の検証を
```python
serializer.is_valid
```
で行います。

あとはシリアライズしたシリアライザインスタンスをシリアライザのsaveメソッドに渡せば完了です。

もしserializerでの入力値の検証が終わっているかつ保存処理が実行される前に何かしたい場合は、perform_createをview内でオーバーライドしましょう。
裏を返せば、簡単にcreateメソッドをオーバーライドするなということです。
どうせcreateメソッドをオーバーライドしたところで、シリアライズすることと入力値の検証をしないといけないことは変わらないので。
Djangoがプログラマに最低限のところだけオーバーライドしなよ。と伝えてくれてるわけです。

**perform_creteの使い方例**
特定のModelのデータをsaveした直後にひもづくレコードを作りたい時

```python
def perform_create(self, serializer):
    instance = serializer.save()
    Profile.objects.create(user=instance)
```


## querysetを使う

mixins.CreateModelMixin以外のmixinは、全てquerysetを使います。
そのため、mixinがquerysetを扱うためによく使うメソッドを覚えておきましょう。

viewを作る際にmixinsと一緒にほぼからなず一緒に継承するGenericViewsetにはこのように書かれています
```python
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass
```
>does include the base set of generic view behavior, such as the `get_object` and `get_queryset` methods.


    
とあるように、get_objectとget_querysetのような「汎用的な」セットが含まれている、とあります。

特にget_querysetはよく使いますので覚えておいてください


**1. get_queryset**
```python
def get_queryset(self):
    """
    Get the list of items for this view.
    This must be an iterable, and may be a queryset.
    Defaults to using `self.queryset`.

    This method should always be used rather than accessing `self.queryset`
    directly, as `self.queryset` gets evaluated only once, and those results
    are cached for all subsequent requests.

    You may want to override this if you need to provide different
    querysets depending on the incoming request.

    (Eg. return a list of items that is specific to the user)
    """
    assert self.queryset is not None, (
        "'%s' should either include a `queryset` attribute, "
        "or override the `get_queryset()` method."
        % self.__class__.__name__
    )

    queryset = self.queryset
    if isinstance(queryset, QuerySet):
        # Ensure queryset is re-evaluated on each request.
        queryset = queryset.all()
    return queryset
```
view内で定義されたquerysetを返します。querysetは必ず定義しないといけません。
コードにあるようにquerysetがないとエラーが起きます。
view内でquerysetを自分用にカスタマイズしたい時は、このget_querysetをオーバーライドします。


以上になります。読んでいただきありがとうございます。