Ошибка контекста при тестировании URL RESTful API в Django - PullRequest
0 голосов
/ 20 февраля 2020

Уважаемое сообщество и форум,

Я отвечаю за разработку URL-адресов RESTful API для проекта веб-сайта. Однако, когда дело доходит до тестирования, я получаю эту ошибку:

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

Сериализатор (извините за уродливый код):

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)

Для теста:

# 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,
)

Мне все еще интересно, должен ли контекст передаваться изнутри сериализатора или из теста.

Вот тоже представление:

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)

Любая помощь с благодарностью!

Спасибо

Роланд

1 Ответ

1 голос
/ 20 февраля 2020

Правильно, поэтому с этим набором настроек вам придется инициализировать сериализатор с контекстом:

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

get_serializer_context() предоставляется по умолчанию в наборах DRF.

...