0

Dear community and forum,

I am in charge of developing RESTful API URLs for a website project. However, when it comes to testing I have got that error:

self = HyperlinkedIdentityField('api:request') value = <ResourceRequest: JoKLLwwKqxrkrwWmcjOWzIscGzpsbgWJqRAOZabnwxQpiEDRfifeZhvzpRRp...ewyOFcaQVhchYNVIhUoiWBzKMrFYvYQBMNRZsLFfOZSjclHUXwyXZQHxjMtbHvWefMIlyZqvTvXqiu> def to_representation(self, value): assert 'request' in self.context, ( "`%s` requires the request in the serializer" " context. Add `context={'request': request}` when instantiating " "the serializer." % self.__class__.__name__ ) E AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer. /usr/lib/python2.7/site-packages/rest_framework/relations.py:351: AssertionError 

The serialiser is (sorry for the ugly code so far):

class ResourceRequestSerializer(serializers.ModelSerializer): # context = self.kwargs.get('context', None) # request = kwargs['context']['request'] # print(kwargs) view_name = 'api:request' url = serializers.HyperlinkedIdentityField(view_name) # print(self) # url = URLField(view_name=view_name, read_only=True, many=True) # url = serializers.SerializerMethodField() support_level = serializers.SerializerMethodField() originator = BriefUCLProfileSerializer(source='originator.ucl_profile') sponsor = BriefUCLProfileSerializer() versioned_dependencies = serializers.StringRelatedField(many=True) types_of_work = serializers.StringRelatedField(many=True) previous = serializers.SerializerMethodField() status_history = RequestStatusChangeSerializer(many=True) 

For the test:

# Change the status through a POST request response = self.app.post( reverse( 'api:request', args=[request1.pk], ), params={ 'context': request1, 'format': 'json', 'status': ResourceRequest.STATUS_APPROVED, }, # context=request1, headers=self.auth_headers, ) 

I am still wondering if the context has to be passed from within the serialiser or from the test.

Here is the view too:

class ResourceRequestAPIView(RetrieveAPIView): """Retrieve an individual resource request by pk and optionally update status""" serializer_class = ResourceRequestSerializer permission_classes = (IsAuthenticated,) authentication_classes = (TokenAuthentication, SessionAuthentication) def get_object(self): try: return ResourceRequest.objects.get(pk=self.kwargs.get('pk')) except ResourceRequest.DoesNotExist: raise Http404 def post(self, request, *args, **kwargs): resource_request = self.get_object() status = request.data['status'] if status != ResourceRequest.STATUS_SUBMITTED: # Change the status resource_request.set_status(status, request.user) # And send emails request_url = request.build_absolute_uri( reverse('api:request', args=[resource_request.pk]) ) send_emails(resource_request, request_url=request_url, ) serializer = ResourceRequestSerializer(resource_request) return Response(serializer.data) 

Any help greatly appreciated !

Thank you

Roland

2
  • 1
    Show us the code for your view/viewset too; that's the place that should set the context. Commented Feb 20, 2020 at 11:15
  • @AKX Here is the view. Hope it helps ! Commented Feb 20, 2020 at 11:31

1 Answer 1

1

Right, so with that viewset in hand, you'll have to initialize the serializer with the context:

serializer = ResourceRequestSerializer( resource_request, context=self.get_serializer_context(), ) 

get_serializer_context() is provided by default by DRF viewsets.

Sign up to request clarification or add additional context in comments.

6 Comments

thank you, that worked ! For the sake of argument, anytime there is a GET/POST request, the context has to be passed from the view to the serialiser ?
If the serializer requires context for something, sure.
you can use the generic function provided: self.get_serializer() (just like the mixins use) as well - that function already calls the self.get_serializer_context() and adds it to the serializer being instantiated
@henriquesalvaro OK ! That's good to know thanks :) However, how would you specify a serializer of choice ? In other words, it looks to me that the self.get_serializer() returns a generic one ?
it returns the serializer defined in your class through the serializer_class variable. you can check it here and here
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.