#Serializerを簡単にいうと!
モデルオブジェクトをJSONに変換してくれる!
それでは
今回はBookオブジェクトを取得する際に、
ForeignKeyで参照しているAuthorをオブジェクトも含めて取得します!!!!!!!!!!!!
#modelを定義する
サンプルのモデルです!
Book
モデルはAuthor
モデルを参照しています!
class AbstractModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
is_deleted = models.CharField(max_length=1, default='0')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Author(AbstractModel):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
class Book(AbstractModel):
title = models.CharField(max_length=128)]
sub_title = models.CharField(max_length=128)]
price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
author = models.ForeignKey(Author, on_delete=models.PROTECT, blank=True, null=True)
#参照元のモデルも一緒に取得する
Viewを定義する
genericsのListAPIViewを使って取得APIを作成します!
author
モデルも取得するのでquerysetには
select_related
でauthorを指定しておきます。
all()
なのでも取得することは可能ですが、select_related.('author')
を
事前に指定しておくことで、発行するSQLを削減できます!!
from django_filters import rest_framework as filters
from rest_framework import generics
from book.models import Book, Author
from book.serializers import BookSerializer
class ListBook(generics.ListAPIView):
"""Bookを一覧取得するAPI"""
queryset = Book.objects.select_related('author')
serializer_class = BookSerializer
filter_backends = [filters.DjangoFilterBackend]
filterset_fields = '__all__'
Serializerに参照元Serializerを定義する
BookSerializer
のフィールドに関連先Serializerを定義することができます!
これで関連先のモデルも取得することができます!!!
ただここで一つ注意なのは参照元のserializerを
定義する時にフィールド名がlookupに関係しているので間違えないようにしてください!!
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
class Meta:
model = Book
fields = '__all__'
結果がこちらです!!!!
出力結果にはサンプルモデルでは省いたデータも出力されちゃってます!!
飛ばしてください!!
#参照先のモデルを取得する
先ほどは、Bookモデルと参照元のAuthor
モデルも取得しましたが、
逆に、Author
からBook
を取得したいと思います!!。
方法は簡単です!
##Viewを定義する
ListAPIViewを使って取得していきたいと思います。
今回は、select_related
などせずにそのままall()
で問題ありません。
class ListAuthor(generics.ListAPIView):
"""Authorを取得する"""
queryset = Author.objects.all()
serializer_class = AuthorBookSerializer
filter_backends = [filters.DjangoFilterBackend]
filterset_fields = '__all__'
Serializerの定義
参照先のモデルを取得するため、book_set
となっています!
これでAPIをリクエストするとAuthorとBookが取得することができます。
この時に、BookSerializer
にauthor = AuthorSerializer()
を残しておくと
book
取得した時にさらにauthor
を再び取得してしまうので注意。
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
class AuthorBookSerializer(serializers.ModelSerializer):
book_set = BookSerializer(many=True)
class Meta:
model = Author
fields = '__all__'
結果がこちらです!!!!
以上になります!