建表
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 __str__(self): return '%d: %s' % (self.order, self.title)
一、字符串相关领域
StringRelatedField
可以使用其方法表示关系的目标。__str__
class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.StringRelatedField(many=True) # 此字段只读 参数many:如果应用于多人关系,应该将此参数设置为True class Meta: model = Album fields = ['album_name', 'artist', 'tracks']
将会序列化为以下数据结构表示
{ 'album_name': 'Things We Lost In The Fire', 'artist': 'Low', 'tracks': [ '1: Sunflower', # order:title '2: Whitetail', '3: Dinosaur Act', ... ] }
二、主键相关领域
PrimaryKeyRelatedField
可以使用其主键表示关系的目标。
序列化器如下
class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) #默认情况下,此字段是读写字段,但您可以使用标记更改此行为。read_only
class Meta: model = Album fields = ['album_name', 'artist', 'tracks']
参数:
queryset
- 用于模型实例查找的查询集在验证字段输入时。关系必须明确设置查询集,或设置查询集。read_only=True
many
- 如果应用于多人关系,您应该将此参数设置为。True
allow_null
- 如果设置为,字段将接受无效关系的值或空字符串。默认为 。True
None
False
pk_field
- 设置为控制主键值的序列化/去除化的字段。例如,将 UUID 主键序列化为其紧凑的六角表示。pk_field=UUIDField(format='hex')
将会序列化为以下数据结构表示
{ 'album_name': 'Undun', 'artist': 'The Roots', 'tracks': [ 89, 90, 91, ... ] }
三、超链接相关领域
HyperlinkedRelatedField
可用于使用超链接表示关系的目标。
序列化器如下
class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.HyperlinkedRelatedField( many=True, read_only=True, view_name='track-detail' ) # 默认情况下,此字段是读写字段,但您可以使用标记更改此行为。read_only
class Meta: model = Album fields = ['album_name', 'artist', 'tracks']
注意:
此字段是专为映射到接受单个 URL 关键字参数的 URL 的对象设计的,该参数是使用和参数设置的。lookup_field
lookup_url_kwarg
这适用于包含单个主键或作为 URL 一部分的 slug 参数的网址。
如果您需要更复杂的超链接表示,则需要自定义字段,如下所示自定义超链接字段部分所述。
参数:
view_name
- 应用作关系目标的视图名称。如果您使用的是标准路由器类,这将是一个具有格式的字符串。需要。<modelname>-detail
queryset
- 用于模型实例查找的查询集在验证字段输入时。关系必须明确设置查询集,或设置查询集。read_only=True
many
- 如果应用于多人关系,您应该将此参数设置为。True
allow_null
- 如果设置为,字段将接受无效关系的值或空字符串。默认为 。True
None
False
lookup_field
-目标上的字段,应用于查找。应对应引用视图上的URL关键字参数。默认值是 。'pk'
lookup_url_kwarg
-URL配置中定义的关键字参数的名称,该名称对应于查找字段。默认使用与 . 相同的值。lookup_field
format
- 如果使用格式后缀,超链接字段将使用相同的格式后缀的目标,除非通过使用参数覆盖。format
将会序列化为以下数据结构表示
{ '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
可用于使用目标上的字段表示关系的目标。
序列化器如下
class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.SlugRelatedField( many=True, read_only=True, slug_field='title' ) 默认情况下,此字段是读写字段,但您可以使用标记更改此行为。read_only
用作读写字段时,您通常希望确保 slug 字段与模型字段对应。SlugRelatedField
unique=True
class Meta: model = Album fields = ['album_name', 'artist', 'tracks']
参数:
slug_field
-目标上的字段应用于表示它。这应该是一个能够唯一识别任何给定实例的字段。例如。需要username
queryset
- 用于模型实例查找的查询集在验证字段输入时。关系必须明确设置查询集,或设置查询集。read_only=True
many
- 如果应用于多人关系,您应该将此参数设置为。True
allow_null
- 如果设置为,字段将接受无效关系的值或空字符串。默认为 。True
None
False
将会序列化为以下数据结构表示
{ 'album_name': 'Dear John', 'artist': 'Loney Dear', 'tracks': [ 'Airport Surroundings', 'Everything Turns to You', 'I Was Only Going Out', ... ] }
五、嵌套关系
这种嵌套关系可以通过使用序列化器作为字段来表示。
如果该字段用于表示对多关系,则应将标志添加到序列化字段中。many=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']
将会序列化为以下数据结构表示
>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse') >>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245) <Track: Track object> >>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264) <Track: Track object> >>> Track.objects.create(album=album, order=3, title='Encore', duration=159) <Track: Track object> >>> serializer = AlbumSerializer(instance=album) >>> serializer.data { '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}, ... ], }
七、可写嵌套序列化器
默认情况下,嵌套序列化器仅读取。如果您想支持将书面操作支持到嵌套序列化字段,则需要创建和/或方法,以便明确指定如何保存儿童关系:create()
update()
序列化器如下
class TrackSerializer(serializers.ModelSerializer): class Meta: model = Track fields = ['order', 'title', 'duration'] class AlbumSerializer(serializers.ModelSerializer): tracks = TrackSerializer(many=True) class Meta: model = Album fields = ['album_name', 'artist', 'tracks'] def create(self, validated_data): tracks_data = validated_data.pop('tracks') album = Album.objects.create(**validated_data) for track_data in tracks_data: Track.objects.create(album=album, **track_data) return album >>> data = { '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}, ], } >>> serializer = AlbumSerializer(data=data) >>> serializer.is_valid() True >>> serializer.save() <Album: Album object>
八、自定义关系字段
我们可以定义一个关系字段,以便使用其订购、标题和持续时间将曲目序列化为自定义字符串表示:
import time class TrackListingField(serializers.RelatedField): def to_representation(self, value): duration = time.strftime('%M:%S', time.gmtime(value.duration)) return 'Track %d: %s (%s)' % (value.order, value.name, duration) class AlbumSerializer(serializers.ModelSerializer): tracks = TrackListingField(many=True) class Meta: model = Album fields = ['album_name', 'artist', 'tracks']
其余关系,官方文档序列化关系 - 詹戈 REST 框架 (django-rest-framework.org)