Bud
Bud

Reputation: 1491

Django rest framework - hyperlinking non-model serializer fields

I'm struggling to figure out how to implement the Hyperlinked relationships for non-model querysets. I have a viewset:

class GGGViewSet(viewsets.ViewSet):

    def list(self, request):
        serializer_class = manufacture_serializer(ar)
        serializer = serializer_class(
            instance = sample.values(), many=True
        )
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        try:
            anobject = sample[pk]
        except KeyError:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except ValueError:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        serializer_class = manufacture_serializer(ar)
        serializer = serializer_class(instance=anobject)

        return Response(serializer.data)

I am trying to get the value resource at /data/trait/ to be rendered as a link, where:

trait-list

data/trait/
{
    "value": 12334,
    "another_value": 45672, 
}

trait-detail

data/trait/value/

{   
    "value":12334
}

Attempted:

url = serializers.HyperlinkedIdentityField(view_name='trait-list')

Error: AttributeError at /asvo/data/trait/ 'AObj' object has no attribute 'pk'.

Any ideas on the best way to approach this would be appreciated. :)

Upvotes: 1

Views: 662

Answers (1)

CaffeineFueled
CaffeineFueled

Reputation: 581

You were probably quite close. Based on the information provided, here's something that demonstrates HyperlinkedIdentityField usage without relying on an actual Django model. I had to use my imagination when filling in the details of your architecture.

from rest_framework import routers
from rest_framework import serializers
from rest_framework import status
from rest_framework import viewsets
from rest_framework.response import Response


# This goes in the URL routing file
router = routers.DefaultRouter()
router.register(r'trait', GGGViewSet, base_name='trait')
urlpatterns = router.urls


# The "model"
class Thing(object):
    def __init__(self, pk, value, another_value):
        self.pk = pk
        self.value = value
        self.another_value = another_value


# The "queryset"
sample = {
    '1': Thing(1, 12334, 45672),
    '2': Thing(2, 12335, 45673),
    '3': Thing(3, 12336, 45674)
}


# The serializer
class manufacture_serializer(serializers.Serializer):
    pk = serializers.HyperlinkedIdentityField(
        view_name='trait-detail', read_only=True)
    value = serializers.IntegerField()
    another_value = serializers.IntegerField()

    class Meta:
        fields = ['pk', 'value', 'another_value']


# The view
class GGGViewSet(viewsets.ViewSet):

    def list(self, request):
        serializer = manufacture_serializer(
            instance=sample.values(), many=True, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        try:
            anobject = sample[pk]
        except KeyError:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except ValueError:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        serializer = manufacture_serializer(
            instance=anobject, context={'request': request})

        return Response(serializer.data)

I did not fully understand the second half of the question regarding the data/trait/ and data/trait/value/, but hopefully this is enough to further you along.

Cheers!

Upvotes: 1

Related Questions