b_p*_*kes 5 django serialization django-rest-framework
How can I add a custom hyperlink field in a serializer? I would like to have a hyperlink field in my serializer that has query params in it. Since there is no way to pass query params from HyperlinkedRelatedField or HyperlinkedIdentityField as far as I know, I've tried using a SerializerMethodField. However, this only serializes to a string, and is not a clickable URL when I visit the API through my browser. My code looks something like this:
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
Run Code Online (Sandbox Code Playgroud)
Also, I am having trouble understanding the difference between a HyperlinkedRelatedField and a HyperlinkedIdentityField, so a brief explanation would be appreciated.
这应该可以解决问题:
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
Run Code Online (Sandbox Code Playgroud)
rest_framework中的反向函数采用一个视图名称(无论您要链接到哪个视图),一个args列表(在这种情况下为对象ID)或kwargs,以及一个请求对象(可以在序列化器内部访问)self.context['request'])。此外,它还可以使用要传递给它的format参数和任何其他参数(作为字典)。
然后,反向功能将为您构建一个漂亮的,格式完整的URL。您可以向其中添加查询参数,只需?{}&{}&{}在结果变量中添加尽可能多的参数,然后在format函数中“ param = foo”下方的一系列查询参数中添加所需的其他参数即可。
的HyperlinkedIdentityField使用正被序列化的对象本身。因此HyperlinkedIdentifyField,正在使用a 代替您的主键字段,MyModel因为您正在使用a HyperlinkedModelSerializer,它HyperlinkedIdentityField为要序列化的对象本身的pk 创建一个a 。
该HyperlinkedRelatedField用来定义相关对象超链接关系。因此,如果存在MySecondModel与外键的关系,MyModel并且您希望在MyModel序列化程序上具有指向所有相关MySecondModel对象的超链接,则应使用HyperlinkedRelatedField这样的方式(请记住将新字段添加到Meta中的fields属性中):
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
Run Code Online (Sandbox Code Playgroud)
如果它是一个OneToOneField而不是ForeignKey字段,MySecondModel那么您将设置many = False。
希望这可以帮助!