這兩天一直在學(xué)習(xí) Django Rest Framework 這個(gè)框架,這是一個(gè)非常流行的 REST API 框架宰衙,深度整合 Django幅狮。但與傳統(tǒng) MVC 模式的不同, Django REST Framework 在使用過(guò)程中寞宫,需要理解一些新的東西萧福。結(jié)合官方 API 分享一下框架中關(guān)于序列化關(guān)系模型的理解。
序列化模型與序列化關(guān)系模型
序列化模型辈赋,顧名思義统锤,即對(duì) models 里的數(shù)據(jù)模型作序列化。而序列化關(guān)系模型則是對(duì) models 里數(shù)據(jù)模型中帶有關(guān)系的如 ForeignKey
, ManyToManyField
和 OneToOneField
字段作序列化炭庙。Django Rest Framework 提供了靈活的序列化關(guān)系模型饲窿,讓開(kāi)發(fā)者可以自由定制序列化數(shù)據(jù)模型。
序列化關(guān)系模型
根據(jù)官方的例子來(lái)看一下每一個(gè)關(guān)系模型的介紹焕蹄。
數(shù)據(jù)模型如下:
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class Meta:
unique_together = ('album', 'order')
ordering = ['order']
def __unicode__(self):
return '%d: %s' % (self.order, self.title)
StringRelatedField
使用 StringRelatedField
將返回一個(gè)對(duì)應(yīng)關(guān)系 model 的 __unicode__()
方法的字符串逾雄。
這個(gè)字段是只讀的。
參數(shù):
-
many
如果應(yīng)用于多對(duì)多關(guān)系,則應(yīng)將此參數(shù)設(shè)置為True
序列化模型如下
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.StringRelatedField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
序列化結(jié)果如下:
{
'album_name': 'Things We Lost In The Fire',
'artist': 'Low',
'tracks': [
'1: Sunflower',
'2: Whitetail',
'3: Dinosaur Act',
...
]
}
PrimaryKeyRelatedField
使用 PrimaryKeyRelatedField
將返回一個(gè)對(duì)應(yīng)關(guān)系 model 的主鍵鸦泳。
參數(shù):
-
queryset
用于在驗(yàn)證字段輸入時(shí)模型實(shí)例查找银锻。 關(guān)系必須明確設(shè)置queryset
,或設(shè)置read_only = True
-
many
如果是對(duì)應(yīng)多個(gè)的關(guān)系做鹰,就設(shè)置為True
-
allow_null
如果設(shè)置為True
击纬,則該字段將接受None
的值或?yàn)榭盏年P(guān)系的空字符串。默認(rèn)為False
-
pk_field
設(shè)置為一個(gè)字段以控制主鍵值的序列化/反序列化钾麸。例如更振,pk_field = UUIDField(format ='hex')
將UUID主鍵序列化為緊湊的十六進(jìn)制表示。
序列化模型如下
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
序列化結(jié)果如下:
{
'album_name': 'Undun',
'artist': 'The Roots',
'tracks': [
89,
90,
91,
...
]
}
HyperlinkedRelatedField
使用 HyperlinkedRelatedField
將返回一個(gè)超鏈接饭尝,該鏈接指向?qū)?yīng)關(guān)系 model 的詳細(xì)數(shù)據(jù)肯腕,view-name
是必選參數(shù),為對(duì)應(yīng)的視圖生成超鏈接钥平。
參數(shù):
-
view_name
用作關(guān)系目標(biāo)的視圖名稱实撒。如果使用的是標(biāo)準(zhǔn)路由器類,那么它的格式為<modelname>-detail
的字符串 -
queryset
驗(yàn)證字段輸入時(shí)用于模型實(shí)例查詢的查詢器涉瘾。關(guān)系必須明確設(shè)置queryset
知态,或設(shè)置read_only = True
-
many
如果應(yīng)用于多對(duì)多關(guān)系,則應(yīng)將此參數(shù)設(shè)置為True
-
allow_null
如果設(shè)置為True
立叛,則該字段將接受None
的值或?yàn)榭盏年P(guān)系的空字符串肴甸。默認(rèn)為False
-
lookup_field
應(yīng)該用于查找的目標(biāo)上的字段。應(yīng)該對(duì)應(yīng)于引用視圖上的URL
關(guān)鍵字參數(shù)囚巴。默認(rèn)值為pk
-
lookup_url_kwarg
與查找字段對(duì)應(yīng)的URL conf
中定義的關(guān)鍵字參數(shù)的名稱原在。默認(rèn)使用與lookup_field
相同的值 -
format
如果使用format
后綴,超鏈接字段將對(duì)目標(biāo)使用相同的format
后綴彤叉,除非使用format
參數(shù)進(jìn)行覆蓋庶柿。
序列化模型如下
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.HyperlinkedRelatedField(
many=True,
read_only=True,
view_name='track-detail'
)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
序列化結(jié)果如下:
{
'album_name': 'Graceland',
'artist': 'Paul Simon',
'tracks': [
'http://www.example.com/api/tracks/45/',
'http://www.example.com/api/tracks/46/',
'http://www.example.com/api/tracks/47/',
...
]
}
SlugRelatedField
使用 SlugRelatedField
將返回一個(gè)指定對(duì)應(yīng)關(guān)系 model 中的字段,需要擦參數(shù) slug_field
中指定字段名稱秽浇。
參數(shù):
-
slug_field
應(yīng)該用于表示目標(biāo)的字段浮庐。這應(yīng)該是唯一標(biāo)識(shí)任何給定實(shí)例的字段。例如username
柬焕。這是必選參數(shù) -
queryset
驗(yàn)證字段輸入時(shí)用于模型實(shí)例查詢的查詢器审残。 關(guān)系必須明確設(shè)置queryset
,或設(shè)置read_only = True
-
many
如果應(yīng)用于多對(duì)多關(guān)系斑举,則應(yīng)將此參數(shù)設(shè)置為True
-
allow_null
如果設(shè)置為True
搅轿,則該字段將接受None
的值或?yàn)榭盏年P(guān)系的空字符串。默認(rèn)為False
序列化模型如下
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='title'
)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
序列化結(jié)果如下:
{
'album_name': 'Dear John',
'artist': 'Loney Dear',
'tracks': [
'Airport Surroundings',
'Everything Turns to You',
'I Was Only Going Out',
...
]
}
HyperlinkedIdentityField
使用 HyperlinkedIdentityField
將返回指定 view-name
的超鏈接的字段富玷。
參數(shù):
-
view_name
應(yīng)該用作關(guān)系目標(biāo)的視圖名稱璧坟。如果您使用的是標(biāo)準(zhǔn)路由器類既穆,則它將是格式為<model_name>-detail
的字符串。必選參數(shù) -
lookup_field
應(yīng)該用于查找的目標(biāo)上的字段雀鹃。應(yīng)該對(duì)應(yīng)于引用視圖上的URL
關(guān)鍵字參數(shù)幻工。默認(rèn)值為pk
-
lookup_url_kwarg
與查找字段對(duì)應(yīng)的URL conf
中定義的關(guān)鍵字參數(shù)的名稱。默認(rèn)使用與lookup_field
相同的值 -
format
如果使用format
后綴黎茎,超鏈接字段將對(duì)目標(biāo)使用相同的format
后綴囊颅,除非使用format
參數(shù)進(jìn)行覆蓋
序列化模型如下
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')
class Meta:
model = Album
fields = ('album_name', 'artist', 'track_listing')
序列化結(jié)果如下:
{
'album_name': 'The Eraser',
'artist': 'Thom Yorke',
'track_listing': 'http://www.example.com/api/track_list/12/',
}
嵌套序列化關(guān)系模型
在序列化模型中指定嵌套序列化關(guān)系模型將返回一個(gè)該嵌套序列化關(guān)系模型對(duì)應(yīng)的數(shù)據(jù)模型中序列化的數(shù)據(jù)。
讀起來(lái)有些拗口傅瞻,看例子吧踢代。
參數(shù):
-
many
如果應(yīng)用于多對(duì)多關(guān)系,則應(yīng)將此參數(shù)設(shè)置為True
序列化模型如下
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ('order', 'title', 'duration')
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
序列化結(jié)果如下:
{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
],
}