Django Rest Framework – Custom Hyperlink field in serializer

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.

Col*_*cks 5

这应该可以解决问题:

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。

希望这可以帮助!