TL;DR
- many=Trueが指定されると、Serializerクラスの__new__メソッドでそれが確認され、ListSerializerのインスタンスが生成されます。
- ListSerializerはリスト内の各オブジェクトをシリアライズするために使用されます。
- ListSerializerはBaseSerializerおよびSerializerクラスから自動的に呼び出されます。
rest_framework/serializers.py
class BaseSerializer(Field):
# ~~ 省略 ~~
def __new__(cls, *args, **kwargs):
# We override this method in order to automatically create
# `ListSerializer` classes instead when `many=True` is set.
if kwargs.pop('many', False):#こいつだ!!!
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
カスタムメソッド
models.py
from django.db import models
class Books(models.Model):
hcode = models.CharField(primary_key=True, max_length=13)
hname = models.CharField(max_length=30, blank=True, null=True)
views.py
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework import viewsets,response
from .models import Books
from .serializers import BookSerializer
class BooksAPIView(viewsets.ModelViewSet):
queryset = Books.objects.db_manager("sqlserver").all()
serializer_class = BookSerializer
# カスタムアクション
@action(detail=False, methods=['get'])
def custom_action(self, request):
hcode :str = request.GET.get('hcode', None)
fmthcode :str = ('5'+(('000000000000'+hcode)[-12:]))
d = Books.objects.db_manager("sqlserver").filter(hcode=fmthcode)
s = BookSerializer(d,many=True) # filterやallにより戻り値がListの場合はmany=Trueを指定する
return response.Response({"data": s.data})
urls.py
from django.urls import path,include
from rest_framework import routers
from .views import BooksAPIView
router = routers.DefaultRouter()
router.register('books', BooksAPIView)
urlpatterns = [
path('', include(router.urls)),
# 他のルートもここに追加する場合があります
]
-
http://127.0.0.1:8000/api/books/
:通常このアドレスにアクセスすると一覧が取得される(Listが帰ってくる) -
http://127.0.0.1:8000/api/books/custom_action?hcode=30000
:このアドレスにアクセスするとCRUD以外のviews.py
で定義したアクションを呼び出す事ができる
シリアライズしてレスポンスを返す方法
querysetの結果が一つの場合
views.py
queryset = Books.objects.db_manager("sqlserver").get(pk=1)
result = BookSerializer(queryset)
return response.Response({"data": result})
複数の場合
- よくわからない引数をシリアライザに渡している...
views.py
queryset = Books.objects.db_manager("sqlserver").all()
result = BookSerializer(queryset,many=True)# many = Trueとはなんだ?
return response.Response({"data": result.data}) # .dataが必要だよ
- そこで調べてみると・・・
rest_framework/serializers.py
の中にいました。
rest_framework/serializers.py
class BaseSerializer(Field):
# ~~ 省略 ~~
def __new__(cls, *args, **kwargs):
# We override this method in order to automatically create
# `ListSerializer` classes instead when `many=True` is set.
if kwargs.pop('many', False):#こいつだ!!!
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)