Reputation: 35
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
Upvotes: 0
Views: 77
Reputation: 169388
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.
Upvotes: 1