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

后端 未结 7 1874
陌清茗
陌清茗 2021-01-31 03:22

I want to create a many-to-many relationship where one person can be in many clubs and one club can have many persons. I added the models.py and

相关标签:
7条回答
  • 2021-01-31 04:01

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

    0 讨论(0)
  • 2021-01-31 04:01

    Following MDT's response, I use django-rest-framework, and solve it by changing request to request._request.

    serializer_context = {'request': Request(request._request)}
    
    0 讨论(0)
  • 2021-01-31 04:17

    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/.

    0 讨论(0)
  • You may simply solve it by changing the instantiation (in views.py) to thing like this:

    your_serializer = YourModelSerializer(YourQuerySet_or_object, many=True,context={'request':request})
    
    0 讨论(0)
  • 2021-01-31 04:19

    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")
    ...
    
    0 讨论(0)
  • 2021-01-31 04:19

    You can simply pass None to 'request' key in context in situations where you just need the relative URL, e.g; testing a serializer in command line.

    serializer = YourModelSerializer(modelInstance_or_obj, context={'request': None})
    
    0 讨论(0)
提交回复
热议问题