Django queryset使うやつと使わないViewSetを意識する
querysetを使わない
mixins.CreateModelMixin
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に突っ込んでシリアライズし、入力値の検証を
serializer.is_valid
で行います。
あとはシリアライズしたシリアライザインスタンスをシリアライザのsaveメソッドに渡せば完了です。
もしserializerでの入力値の検証が終わっているかつ保存処理が実行される前に何かしたい場合は、perform_createをview内でオーバーライドしましょう。
裏を返せば、簡単にcreateメソッドをオーバーライドするなということです。
どうせcreateメソッドをオーバーライドしたところで、シリアライズすることと入力値の検証をしないといけないことは変わらないので。
Djangoがプログラマに最低限のところだけオーバーライドしなよ。と伝えてくれてるわけです。
perform_creteの使い方例
特定のModelのデータをsaveした直後にひもづくレコードを作りたい時
def perform_create(self, serializer):
instance = serializer.save()
Profile.objects.create(user=instance)
querysetを使う
mixins.CreateModelMixin以外のmixinは、全てquerysetを使います。
そのため、mixinがquerysetを扱うためによく使うメソッドを覚えておきましょう。
viewを作る際にmixinsと一緒にほぼからなず一緒に継承するGenericViewsetにはこのように書かれています
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
andget_queryset
methods.
とあるように、get_objectとget_querysetのような「汎用的な」セットが含まれている、とあります。
特にget_querysetはよく使いますので覚えておいてください
1. get_queryset
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をオーバーライドします。
以上になります。読んでいただきありがとうございます。