坏程序员担心代码,好程序员担心数据结构和它们之间的关系。
1. 简介
关系字段被用来表示模型之间的关系,能够用在ForeignKey, ManyToManyField and OneToOneField中,也可以颠倒这个关系,也可以自定义关系,如GenericForeignKey
在使用ModelSerializer,最好利用print repr(serializer)检查自动生成的字段内容
2. 关系型序列化字段使用指南
1 使用示例
一张音乐专辑和专辑里的所有歌曲详情
# 专辑类
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:
# 将'album', 'order'设为主键
unique_together = ('album', 'order')
# 设置序列化输出时的排序字段
ordering = ['order']
def __unicode__(self):
return '%d: %s' % (self.order, self.title)
2 StringRelatedField
调用unicode 方法来呈现对象。
class AlbumSerializer(serializers.ModelSerializer):
# 外界只显示歌曲编号和歌曲名字,many为多个对象执行
tracks = serializers.StringRelatedField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
{
'album_name': 'Things We Lost In The Fire',
'artist': 'Low',
'tracks': [
'1: Sunflower',
'2: Whitetail',
'3: Dinosaur Act',
...
]
}
3 PrimaryKeyRelatedField
使用主键来表示关联的目标,默认情况下该字段是可以读写的,可以利用read_only将其设置为只读
- queryset:设置用于查找的查询集对象,如果没有设置,就需要设置read_only=True
- many:如果对应多个关系对象时
- allow_null:如果设置为True,则允许接收空字符串和None
- pk_field:设置主键的值
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
{
'album_name': 'Undun',
'artist': 'The Roots',
'tracks': [
89,
90,
91,
...
]
}
4 HyperlinkedRelatedField
默认通过主键查询,关系对象显示为一个url
url接受单独的URL关键字参数,利用lookup_field和lookup_url_kwarg设置
url中包含一个单独的主键或者标签参数
如果需要使用更复杂的超链接字段,需要自己自定义
- view_name:被用来表示对象的视图函数名。如果使用标准路由类,那就是-detail。required。
- queryset:用于字段查找和验证的对象查找集。与read_only=True参数二选一
- many:如果对应多个对象时,设置为True
- allow_null:设置为True,则接受字段输入None或者空值
- lookup_field:查询字段名 ,应该与 view_name中的参数一致,默认为’pk’
- lookup_url_kwarg:定义在url中的查询参数的名字,默认使用与lookup_field一样的值
- format:url后缀
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.HyperlinkedRelatedField(
many=True,
read_only=True,
view_name='track-detail'
)
# view_name='track-detail'查询函数,默认使用主键
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
# 接口的显示内容
{
'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/',
...
]
}
5 SlugRelatedField
slug_field使用对象中的某个字段表示对象
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='title'
)
# 使用歌曲名字代表歌曲对象
class Meta:
model = Album
fields = (