LoginSignup
14
18

More than 3 years have passed since last update.

[Django REST Framework] Serializerの使い方

Last updated at Posted at 2021-03-23

実行環境

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モデルを作成しました。

models.py
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を作成します。

serializers.py
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処理を実装できます。

views.py
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
urls.py

router = DefaultRouter()
# Viewでquerysetの記述があればbasenameの設定はいらない
router.register('post',views.PostViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

serializerを使わない場合

views.py
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処理を作成できます!!

参考

以下のページが非常に分かりやすく、参考にさせていただきました。
- https://note.crohaco.net/2018/django-rest-framework-serializer/
- http://i-plug-tech.hatenablog.com/entry/2017/02/10/174050
- https://pigblog.org/django-restframework-basic5

14
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
18