AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context

邮差的信 提交于 2019-12-02 16:44:43

You're getting this error as the HyperlinkedIdentityField expects to receive request in context of the serializer so it can build absolute URLs. As you are initializing your serializer on the command line, you don't have access to request and so receive an error.

If you need to check your serializer on the command line, you'd need to do something like this:

from rest_framework.request import Request
from rest_framework.test import APIRequestFactory

from .models import Person
from .serializers import PersonSerializer

factory = APIRequestFactory()
request = factory.get('/')


serializer_context = {
    'request': Request(request),
}

p = Person.objects.first()
s = PersonSerializer(instance=p, context=serializer_context)

print s.data

Your url field would look something like http://testserver/person/1/.

I have two solutions...

urls.py

1) If you are using a router.register, you can add the base_name:

router.register(r'users', views.UserViewSet, base_name='users')
urlpatterns = [    
    url(r'', include(router.urls)),
]

2) If you have something like this:

urlpatterns = [    
    url(r'^user/$', views.UserRequestViewSet.as_view()),
]

You have to pass the context to the serializer:

views.py

class UserRequestViewSet(APIView):            
    def get(self, request, pk=None, format=None):
        user = ...    
        serializer_context = {
            'request': request,
        }
        serializer = api_serializers.UserSerializer(user, context=serializer_context)    
        return Response(serializer.data)

Like this you can continue to use the url on your serializer: serializers.py

...
url = serializers.HyperlinkedIdentityField(view_name="user")
...

I came across the same problem. My approach is to remove 'url' from Meta.fields in serializer.py.

Following Slipstream's answer, I edited my views.py introducing the context and now it works.

class UserViewSet(viewsets.ModelViewSet):

    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().select_related('profile').order_by('-date_joined')
    serializer_class = UserSerializer

    @list_route(methods=['get'], url_path='username/(?P<username>\w+)')
    def getByUsername(self, request, username):
        serializer_context = {
            'request': request,
        }
        user = get_object_or_404(User, username=username)
        return Response(UserSerializer(user, context=serializer_context).data, status=status.HTTP_200_OK)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!