メリット
https://www.django-rest-framework.org/tutorial/3-class-based-views/#using-mixins
Mixin を使うと短くかけるらしい。
def get(self, request, format=None):
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
これが
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
2行ずつで書けるようになるらしい。正気か?
SnippetList を Generics と Mixins を使って書く
from rest_framework import mixins
from rest_framework import generics
mixins, generics, を import
class SnippetList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
APIView の代わりに
ListModelMixin, CreateModelMixin, GenericAPIView,
これらを使い
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
Snippet のオブジェクト全てを queryset 変数に入れて
Snippet のシリアライザーを serializer_class 変数に入れる
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
get でも post でも *args, **kwargs を使うことによって
queryset と serializer_class を使えるようになると推測する。
get の場合は self.list に
Snippets オブジェクトをシリアライズして全て返す
メソッドが入っていて
post の場合は self.create に
request の中のデータをシリアライズして
エラーハンドリングして結果を返す
メソッドが入っている
と推測する。
動作確認しても、問題なく以前と同じように動いた。
SnippetDetail で Generics と Mixin を使う
class SnippetDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
SnippetDetail でも同じように Mixin と Generics のモジュール?を引数にとる。
今回は Mixin では Retrieve, Update, Destory, を使う
get が list ではなく、retrieve になっている。
こちらも問題なく動作確認できた。
詳細での取得も上書きも削除も、恐ろしいほど簡単にかけた。
Generics を使って .list, .create や .retreive, .update, .destroy, をまとめる
さらに簡単に書く方法がある。
Mixin すら使わず、Mixin で使っていた相当のメソッドを最初に Generics でまとめてしまう方法だ。
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
generics.ListCreateAPIView で List, Create
generics.RetrieveUpdateDestroyAPIView
で Retrieve, Update, Destroy,
をモジュールから持ってきてしまえると推測する。
こちらも問題なく動作確認ができた。
まとめ
オブジェクトを取得して
シリアライザにかけて、保存や削除をして〜
と書いていたコードを
class SnippetList(mixins.ListModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
List, Create などの Mixin と Generics を使うことで
return する箇所に self.list() と書くだけで実装できた。
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
また、Generics を使い、最初に Mixin の各メソッドを明記することで
return すら書かずに簡略化して書くことが可能だった。
Top comments (0)