実行環境
MacOS BigSur -- 11.2.1
Python3 -- 3.8.2
Django -- 3.1.7
djangorestframework -- 3.12.2
Django REST Framework(DRF) のシリアライザーとは?!
さて、現在DRFとReactによるWebアプリケーションを作成中なのですが、Djangoでは出てこなかったSerializerでつまづいたのでその使い方をメモがてらにまとめようと思います。
serializerとは
一言で表すと、データの入出力を扱い、モデルでの橋渡しをするクラスのことです。
- シリアライズ(入力):複雑な入力値をモデルに合わせてバリデーションしてレコードに伝える
- デシリアライズ(出力):Model(レコード)を適切な形式にフォーマットしてpythonで扱えるようにする
これらの役割を担っています。DjangoにおけるFormと同じような位置付けのようです。
ModelSerializer
さて、今回はModelSerializerを使用します。
ModelSerializerは、Modelに紐付くFieldを自動的に定義してくれると言う便利なものだそうです。要するにDjangoのModelFormの様なイメージですね。実際にModelSerializerを使用してCURD処理の実装をしてみます。
Serializerを用いてCURD処理の実装
Model
まずは簡単なPostモデルを作成しました。
class Post(models.Model):
title = models.CharField('タイトル', max_length=50)
text = models.TextField('テキスト')
created_at = models.DateField('作成日', auto_now_add=True)
updated_at = models.DateField('更新日', auto_now=True)
def __str__(self):
return self.title
Serializer
ModelSerializerを用いてPostSerializerを作成します。
from rest_framework import serializers
from backend import models
from backend.models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('title','text','created_at','updated_at','id')
read_only_fields = ('id',)
fields = ('title','text','created_at','updated_at','id')
で指定したカラムを表示できるようになっています。
ちなみに、
read_only_fields = ('id',)
で特定のカラム(ここでは id )を更新不可にできます。この際にread_only_fieldsにはリストまたはタプルでカラムを指定しないとエラーが出ます。
Viewとurl
あとはViewでserializerを指定して、urlに追加するだけで簡単にCRUD処理を実装できます。
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
"""PostオブジェクトのCRUD"""
queryset = Post.objects.all().order_by('-created_at')
serializer_class = PostSerializer
router = DefaultRouter()
# Viewでquerysetの記述があればbasenameの設定はいらない
router.register('post',views.PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
serializerを使わない場合
class PostAll(APIView):
def get(self, request):
try:
post = Post.objects.all().order_by('-created_at')
res_list = [
{
'id': p.id,
'date': p.created_at,
'title': p.title,
}
for p in post
]
return Response(res_list)
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
ちなみに、これまではserializerを用いておらず、viewにこのような記述をしていました。どっからどう見ても非効率でした。。。
と言うことで、このようにシリアライザーを用いて簡単にCRUD処理を作成できます!!
参考
以下のページが非常に分かりやすく、参考にさせていただきました。