关系字段用于表示模型之间的关联 Django中存在ForeignKey、MantToManyField和OneToOneField三种正向关系,以及反向关联和自定义关联 当继承 ModelSerializer 类的时候,包括关系型字段在内的所有字段会自动生成
StringRelatedField
使用对象的 __str__ 方法来表示关联的对象
这个字段其实也就是将关联对象的字符串表示形式的信息拿来,放到自己的序列化类中
供API视图使用并渲染,然后传递给前端
#Model示例
def __str__(self):
return '%d: %s' % (self.order, self.title)
# serializer
info = serializers.StringRelatedField(many=True)
该字段是只读的
PrimaryKeyRelatedField
PrimaryKeyRelatedField 使用关联对象的主键id值来表示对象
info = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
默认情况下,这种字段关联方式是可读可写的。可以通过添加 read_only=True 标识,变成只读
参数:
queryset - 当对字段的输入数据进行验证的时候,用于查询模型实例的查询集。必须显式的提供这个参数,或者设置 read_only=True 。
many - 如果关联的是一个复数数量的对象,必须将此参数设置为 True 。
allow_null - 默认为False。如果设置为 True ,在可空的关联上,该字段将可以接收None 或空字符串。
pk_field - 指定序列化/反序列化过程中,使用的主键字段类型。例如pk_field=UUIDField(format='hex') 将序列化一个UUID主键值
HyperlinkedRelatedField
HyperlinkedRelatedField 使用关联对象的超链接形式来标识关联对象
info = serializers.HyperlinkedRelatedField(many=True,read_only=True,view_name='track-detail')
默认情况下,这种字段关联方式是可读可写的。可以通过添加 read_only=True 标识,变成只读
这种关系字段适合包含单独主键或者slug参数的URLs,
参数:
view_name - 处理关联对象URL的视图。如果你使用的是标准的路由类,它必须是一个<modelname>-detail 格式的字符串。此参数必填
queryset - 当对字段的输入数据进行验证的时候,用于查询模型实例的查询集。必须显式的提供这个参数,或者设置 read_only=True 。
many - 如果关联的是一个复数数量的对象,必须将此参数设置为 True 。
allow_null -默认为False。如果设置为 True ,在可空的关联上,该字段将可以接收None 或空字符串。
lookup_field - 该参数的默认值为 'pk' ,表示用主键id在视图种查找关联的对象,一般我们不需要修改这个参数。它必须和对应视图的URL关键字参数一致,你这里如果改了,在视图中也必须跟着改。
lookup_url_kwarg - 指定上面参数值的名字,一般使用 lookup_field 。大多数情况下,我们不用修改这个参数,默认就好,除非你需要自定义一大堆,不要给自己挖坑。
format - 如果URL种使用了格式后缀,超链接字段将使用同样的格式后缀,除非使用这个 format 参数另外指定后缀形式
SlugRelatedField
SlugRelatedField 使用某个指定的字段的值作为关联对象的表示形式。比如拿对象的名字、或者邮箱、或者昵称、或者地址等等
info = serializers.SlugRelatedField(many=True,read_only=True,slug_field='title')
默认情况下,这种字段关联方式是可读可写的。可以通过添加 read_only=True 标识,变成只读
参数:
slug_field - 指定用来表示关联对象的字段,该参数必填。
queryset - 同上
many - 同上
allow_null - 同上
HyperlinkedIdentityField
这种字段可以使用超链接身份关联,使用较少
该字段只读
view_name - 同前。必填。
lookup_field - 同前
lookup_url_kwarg - 同前
format - 同前
嵌套关联
可以将序列化类作为字段,来表示嵌套关联
如果关联的是一个复数数量的一些,必须将many参数设置为True
class TextSerializer(serializers.ModelSerializer):
# 设置嵌套关联的字段
info = CategorySerializer(many=True,read_only=True)
class Meta:
model = Text
fields = ('url', 'id', 'title', 'content', 'auth', 'category', 'created','info') #序列化
默认情况下,嵌套关联是只读的!如果你想设置可读写的嵌套关联,你必须自己实现create() 与/或 update() 方法,显式地指定如何保存子关系
#示例
def create(self, validated_data):
infos_data = validated_data.pop('info')
text = TextModel.objects.create(**validated_data)
for info_data in infos_data:
CategoryModel.objects.create(text=text, **track_data)
return text
自定义关系类型字段
- 如果现有的关系样式都不适合,那实现一个完全自定义的关系字段
- 要自定义关系类型字段,必须先继承 RelatedField 类
- 然后实现 .to_representation(self, value) 方法
- 此方法将字段的目标作为“value”参数,并应返回对象序列化后的表示形式,“value”参数通常是模型实例
- 如果想实现可读写的关系类型字段,需要实现 .to_internal_value(self, data)方法
- 如果想提供一个基于 context 的动态查询集,需要覆盖 .get_queryset(self) 方法