iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
Modern Web

傳承D的意志~ 邁向Django的偉大航道系列 第 26

[DAY 26] 激戰篇: 如何序列化複數個model

  • 分享至 

  • xImage
  •  

嗨大家好,我是Sean!
過完了連假,總是有'拜託再多一天'的感覺嗚嗚!

那麼,我們今天來講一個實務不可避免會需要使用到的技巧,序列化複數個model。

Serialize multiple model


其實有許多種方法可以達到相同的目的,我們今天就來介紹其中的兩種,能達到序列化複數model的方法。

Extended Serializer


第一種方法我們可以使用extended serializer。

from rest_framework import serializers

class People_extendedSerializer(serializers.ModelSerializer):
    class Meta:
        model = People_extended
        fields = ['field_3', 'field_4', 'field_5']

class PeopleSerializer(serializers.ModelSerializer):
    people_extendeds = People_extendedSerializer(many=True)
    
    class Meta:
        model = People
        fields = '__all__'

我們原先在專案中,就有寫過People的model以及serializer,所以這邊單純拿他來當舉例。
People_extended指的自然就是另外一個model,也就是你想一起序列化的model。

首先,你得先為People_extended寫一個serializer,如同我們先前所寫過的ModelSerializer,他需要model與fields的兩個參數。
接著,我們再改寫People的Serializer。
在PeopleSerializer中嵌入People_extendedSerializer的欄位,特別注意的是,必須添加參數(many=True),才不會報錯!
原因在於,我們前面的serializer中,我們extend的部分有可能是複數個。

例如:

'data': {
    'name': '',
    'bio': '',
    'file' : {
        {
            'id': 1,
        },
        
        {
          'id': 2,  
        }
    
    }
}

在這裡,我們data就像是我們的People model,而file則為People_extended。

有多對一關聯關係


第二種,我們來介紹若兩個model間,有多對一關聯關係該怎麼做:

class DataSerializer(serializers.Serializer):

    class FileTempSerializer(serializers.Serializer):
        class Meta:
            model = File
            exclude = ['data']
    
    file = FileTempSerializer()

    class Meta:
        model = Data
        fields = '__all__'

    def create(self, validated_data):
        file_data = validated_data.pop('file')
        data_instance = Data.objects.create(**validated_data)
        File.objects.create(data=basicdata_instance, **file_data)
        
        return data_instance

我們運用剛剛舉例的data和file的關係來做例子。
File model的欄位中,有一個foreign key(data)關聯到Data的model。

這裡的邏輯其實跟剛才的extend有十之八九像,關鍵的點是,如何共用關聯的欄位。
首先,在File的serializer中,我們先剔除了data,也就是外來鍵的欄位。

而在Data的serializer中,同樣寫下了file的serializer。
但我們必須同時建立data的這個欄位,所以我們改寫create的function。

第一步使用pop,來選出file的object,接著將Data的object寫成變數後,再將它寫成File.objects.create()裡的data指向。如此一來,就可以確定新增時,file serializer中的外來鍵欄位,必定是Data中的instance。

那麼,我們今天的文章就到此結束,感謝大家的收看!
我是Sean,你各位海上的人,我們明天見!
https://ithelp.ithome.com.tw/upload/images/20221011/20151096jBuSzho9P2.jpg


上一篇
[Day 25] 激戰篇: 如何將選項(Choices)欄位變更為外來鍵(FK)
下一篇
[Day 27] 激戰篇: 新世界人人都要會的Docker?
系列文
傳承D的意志~ 邁向Django的偉大航道30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言