1. 程式人生 > >DAY97 - Rest Framework(二)- 序列化元件之Serializer和ModelSerializer

DAY97 - Rest Framework(二)- 序列化元件之Serializer和ModelSerializer

一、序列化元件之Serializer

from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework import serializers
from app01 import models

class AuthorSerializers(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    sex = serializers.CharField(max_length=32)
    
    
class BookSerializers(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    # source 可以指定欄位,可以對欄位重新命名,不使用則前面的變數名必須和表一樣
    book_price = serializers.CharField(max_length=32, source='price')
     
    # 跨表查詢:查詢書本的出版社名
    # 方式一
    # 使用該方法必須重寫Publish表的__str__方法,不然顯示的是publish物件
    # def __str__(self):
    #    return self.name
    # 顯示 "publish": "北京出版社"
    publish = serializers.CharField()
      
        
    # 方式二
    # source可以指定欄位,那麼可以使用基於物件的跨表查詢來引用publish.name
    publish = serializers.CharField(source='publish.name')
    
    
    # 方式三
    # source不僅可以指定欄位,還可以指定方法
    # def test(self):
    #     return self.name
    publish = serializers.CharField(source='publish.test')

    
    # 方法四
    # SerializerMethodField() 可以指定一個方法
    publish = serializers.SerializerMethodField()
    # 方法名必須是get_欄位名,傳入引數obj:當前的book物件
    def get_publish(self,obj):
        ll={'name':obj.publish.name,'email':obj.publish.email}
        return ll
    
    # 方法內部也可以使用序列化元件
    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        # 拿到這本書的所有作者
        authors = obj.authors.all()
        author_ret = AuthorSerializers(authors, many=True)
        return author_ret.data
    
    
class Books(APIView):
    def get(self, request, *args, **kwargs):
        books = models.Book.objects.all()
        ret = BookSerializers(books, many=True)
        return JsonResponse(ret.data, safe=False)

二、序列化元件之ModelSerializer

from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework import serializers
from app01 import models

class AuthorSerializers(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    sex = serializers.CharField(max_length=32)

class BookSerializers(serializers.ModelSerializer):
    # Meta是必須寫的
    class Meta:
        # model:指定表
        model = models.Book
        # fields:顯示的欄位
        # 全部顯示
        fields = '__all__'
        # 部分顯示
        # fields = ['name','price']
        # exclude:不顯示的欄位,exclude和fields不能一塊使用
        # exclude=['publish','authors']
        # depth:跨表顯示的深度,不寫預設為0,一般最好小於3
        # 比如depth=1,就顯示作者資訊和出版社資訊;depth=2,作者詳情表也顯示
        # depth=1

    # 但是這樣欄位名就寫死了,像出版社和作者就只顯示ID
    # 可以重寫欄位
    publish = serializers.CharField(source='publish.name')
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        # 拿到這本書的所有作者
        authors = obj.authors.all()
        author_ret = AuthorSerializers(authors, many=True)
        return author_ret.data


class Books(APIView):
    def get(self, request, *args, **kwargs):
        books = models.Book.objects.all()
        ret = BookSerializers(books, many=True)
        return JsonResponse(ret.data, safe=False)