Search code examples
djangodjango-rest-framework

How to make all Hyperlinks in Django REST Framework relative?


Is there any easy way to use relative to Root urls instead of absolute ones? By default DRF returns something like this:

{
    "url": "http://127.0.0.1:34503/items/4/",
    ...
    "parent": "http://127.0.0.1:34503/items/1/",
    "stargazers": "http://127.0.0.1:34503/items/4/stargazers",
}

I would like it to be:

{
    "url": "/items/4/",
    ...
    "parent": "/items/1/",
    "stargazers": "/items/4/stargazers",
}

Any ideas?

I am using HyperlinkedModelSerializer:

class ItemSerializer(serializers.HyperlinkedModelSerializer):
    stargazers = serializers.HyperlinkedIdentityField(view_name='item-stargazers')

    class Meta:
        model = Item
        fields = ['url', 'id', ..., 'stargazers']

class ItemViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Item.objects.all().order_by('id')
    serializer_class = ItemSerializer

Solution

  • As the documentation on Absolute and relative URLs states:

    If you do want to use relative URLs, you should explicitly pass {'request': None} in the serializer context.

    You thus should serialize this with:

    class ItemSerializer(serializers.HyperlinkedModelSerializer):
        # …
        
        class Meta:
            model = Account
            fields = ['url', id', 'stargazers']

    and then serialize this with:

    ItemSerializer(queryset, context={'request', None})

    For a ViewSet, you can overide the get_serializer_context method:

    class ItemViewSet(viewsets.ReadOnlyModelViewSet):
        # …
    
        def get_serializer_context(self):
            result = super().get_serializer_context()
            result['request'] = None
            return result