Django Rest Framework 嵌套序列化關(guān)系模型
序列化模型與序列化關(guān)系模型
序列化和反序列化
通俗的說(shuō)序列化就是將一個(gè) model 實(shí)例轉(zhuǎn)換為 json 格式的過(guò)程,反序列化則是將 json 格式的數(shù)據(jù)轉(zhuǎn)換為一個(gè) model 實(shí)例的過(guò)程。
序列化模型,即對(duì) models 里的數(shù)據(jù)模型作序列化。這個(gè)在前一篇Django - RESTful使用指南中已經(jīng)涉及到了,這里就不多做說(shuō)明。
序列化關(guān)系模型則是對(duì) models 里數(shù)據(jù)模型中帶有關(guān)系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化。
序列化關(guān)系模型
StringRelatedField : 返回一個(gè)對(duì)應(yīng)關(guān)系 model 的 unicode() 方法的只讀字符串。
PrimaryKeyRelatedField : 返回一個(gè)對(duì)應(yīng)關(guān)系 model 的主鍵。
HyperlinkedRelatedField : 返回一個(gè)超鏈接,該鏈接指向?qū)?yīng)關(guān)系 model 的詳細(xì)數(shù)據(jù),view-name 是必選參數(shù),為對(duì)應(yīng)的視圖生成超鏈接。
SlugRelatedField : 返回一個(gè)指定對(duì)應(yīng)關(guān)系 model 中的字段,需要擦參數(shù) slug_field 中指定字段名稱。
HyperlinkedIdentityField : 返回指定 view-name 的超鏈接的字段。
以上內(nèi)容詳細(xì)的講解參考:https://segmentfault.com/a/1190000010024982#articleHeader5
嵌套序列化關(guān)系模型
ModelSerializer 類能夠讓你自動(dòng)創(chuàng)建一個(gè)具有模型中相應(yīng)字段的Serializer類。
這個(gè) ModelSerializer 類和常規(guī)的 Serializer 類一樣,不同的是:
- 它根據(jù)模型自動(dòng)生成一組字段。
- 它自動(dòng)生成序列化器的驗(yàn)證器,比如unique_together驗(yàn)證器。
- 它默認(rèn)簡(jiǎn)單實(shí)現(xiàn)了.create()方法和.update()方法。
默認(rèn)情況下,所有的模型的字段都將映射到序列化器上相應(yīng)的字段。
如果你希望在模型序列化器中使用默認(rèn)字段的一部分,你可以使用fields或exclude選項(xiàng)來(lái)執(zhí)行此操作。建議你使用fields屬性顯示的設(shè)置要序列化的字段。這樣就不太可能因?yàn)槟阈薷牧四P投鵁o(wú)意中暴露了數(shù)據(jù)。
-
fields :
'__all__' : 表明使用模型中的所有字段。
(field_name1, field_name2....) : 表示只顯示該元組中包含的字段。
eg:
fields = 'all' -
exclude :屬性設(shè)置成一個(gè)從序列化器中排除的字段列表。
eg: exclude = ('create_time', 'age')
嵌套序列化
為了顯示效果創(chuàng)建數(shù)據(jù)模型:
class Student(models.Model):
s_name = models.CharField(max_length=20)
s_tel = models.CharField(max_length=11)
g_id = models.ForeignKey(Grade, related_name='gstu')
class Meta:
db_table = 'student'
class Stuinfo(models.Model):
s_addr = models.CharField(max_length=50)
sid = models.OneToOneField(Student, null=True, related_name='stuinfos')
class Meta:
db_table = 'stuinfo'
class Grade(models.Model):
g_id = models.CharField(max_length=10, unique=True)
g_name = models.CharField(max_length=20)
g_desc = models.CharField(max_length=50)
class Meta:
db_table = 'grade'
方式一:
使用 depth 生成嵌套關(guān)聯(lián):
serializers.py文件:
from rest_framework import serializers
from stu.models import Student, Stuinfo
from grade.models import Grade
class StuSerizlizer(serializers.ModelSerializer):
class Meta:
model = Student
depth = 1
fields = '__all__'
depth選項(xiàng)應(yīng)該設(shè)置一個(gè)整數(shù)值,表明應(yīng)該遍歷的關(guān)聯(lián)深度。通過(guò)depth可以將查詢相關(guān)的外鍵關(guān)系的信息也展示出來(lái)。
結(jié)果如下圖:

方式二:
自定義字段來(lái)展示外鍵信息:
serializers.py文件:
class Stuinfoserializer(serializers.ModelSerializer):
class Meta:
model = Stuinfo
fields = ('s_addr',)
class StuSerizlizer(serializers.ModelSerializer):
stuinfos = Stuinfoserializer()
class Meta:
model = Student
fields = ['pk', 's_name', 's_tel', 'g_id', 'stuinfos']
注意:
stuinfos = Stuinfoserializer()和fields = ['pk', 's_name', 's_tel', 'g_id', 'stuinfos']中的 stuinfos 必須和定義外鍵時(shí)的 related_name 指定的值一致,否則就不能返回結(jié)果并且報(bào)錯(cuò): ' Server Error (500) '.
這里的序列化是不可以創(chuàng)建和更改的,如果要反向可以創(chuàng)建和更改,你可以重構(gòu) ModeSerializer 的 create() 和 update()方法。因?yàn)檫@里有一個(gè)更簡(jiǎn)單的方法去創(chuàng)建一個(gè)可寫嵌套序列化模型,所以就不做演示了。
可寫嵌套序列化模型
在這里有一個(gè)模塊可以輕松幫我們實(shí)現(xiàn)創(chuàng)建一個(gè)可寫的嵌套序列化模型: 'drf_writable_nested
安裝 drf_writable_nested:
pip install drf_writable_nested
serializers.py文件,導(dǎo)入model:
from drf_writable_nested import WritableNestedModelSerializer
class Stuinfoserializer(serializers.ModelSerializer):
class Meta:
model = Stuinfo
fields = ('s_addr',)
class StuSerizlizer(WritableNestedModelSerializer):
stuinfos = Stuinfoserializer()
class Meta:
model = Student
fields = ['pk', 's_name', 's_tel', 'g_id', 'stuinfos']
patch結(jié)果:


使用WritableNestedModelSerializer可以輕松的創(chuàng)建可寫的嵌套序列化模型,這樣將大大縮短我們開發(fā)后端API接口的時(shí)間。