如何在序列化程序中添加自定义超链接字段?我希望在我的序列化程序中有一个包含查询参数的超链接字段。由于我无法从HyperlinkedRelatedField
或HyperlinkedIdentityField
传递查询参数,因此我尝试使用SerializerMethodField
。但是,这只是序列化为字符串,而当我通过浏览器访问API时,它不是可点击的URL。我的代码看起来像这样:
class MySerializer(serializers.HyperlinkedModelSerializer):
custom_field = serializers.SerializerMethodField()
class Meta:
model = MyModel
fields = ('url', 'custom_field')
def get_custom_field(self, obj):
result = '{}?{}'.format(
reverse('my-view'),
urllib.urlencode({'param': 'foo'})
)
return result
此外,我无法理解HyperlinkedRelatedField
和HyperlinkedIdentityField
之间的区别,因此我们将不胜感激。
答案 0 :(得分:4)
这应该可以解决问题:
sed
rest_framework中的反向函数采用视图名称(无论您要链接到哪个视图),args列表(在本例中为对象ID)或kwargs,以及请求对象(可在内部访问) from rest_framework.reverse import reverse
class MySerializer(serializers.HyperlinkedModelSerializer):
custom_field = serializers.SerializerMethodField()
class Meta:
model = MyModel
fields = ('url', 'custom_field')
def get_custom_field(self, obj):
result = '{}?{}'.format(
reverse('my-view', args=[obj.id], request=self.context['request']),
'param=foo'
)
return result
处的序列化程序。它还可以采用格式参数和您想要传递给它的任何额外参数(作为字典)。
反向函数然后为您构建一个漂亮的,完整形成的URL。您只需向结果变量中添加self.context['request']
,然后在?{}&{}&{}
函数内的'param = foo'下面填写一系列查询参数,就可以添加查询参数。想。
format
用于正在序列化的对象本身。因此,使用HyperlinkedIdentityField
代替HyperlinkedIdentifyField
上的主键字段,因为您正在使用MyModel
为要序列化的对象本身的pk创建HyperlinkedModelSerializer
HyperlinkedIdentityField
用于定义与RELATED对象的超链接关系。因此,如果HyperlinkedRelatedField
与MySecondModel
具有外键关系,并且您希望MyModel
序列化程序上包含所有相关MyModel
对象的超链接,那么您将使用MySecondModel
喜欢这样(请记住将新字段添加到Meta中的fields属性中):
HyperlinkedRelatedField
如果它是class MySerializer(serializers.HyperlinkedModelSerializer):
custom_field = serializers.SerializerMethodField()
mysecondmodels = serializers.HyperlinkedRelatedField(
many=True
read_only=True,
view_name='mysecondmodel-detail'
)
class Meta:
model = MyModel
fields = ('url', 'custom_field', 'mysecondmodels')
def get_custom_field(self, obj):
result = '{}?{}'.format(
reverse('my-view', args=[obj.id], request=self.context['request']),
'param=foo'
)
return result
上的OneToOneField而不是ForeignKey字段,那么你可以设置很多= False。
希望这有帮助!