JasonGenX
JasonGenX

Reputation: 5444

Django Rest Framework: Unclear error message

my views.py:

class user_password(generics.UpdateAPIView):
    authentication_classes = ([JSONWebTokenAuthentication])
    serializer_class = user_password_serializer

    def get_queryset(self):
        return User.objects.get(id=self.request.user.id)

But I'm getting this when running it:

AssertionError: Expected view user_password to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field attribute on the view correctly.

I know the serializer is okay because when I use a different type of View for the same thing. It works:

class user_password(APIView):

    authentication_classes = ([JSONWebTokenAuthentication])

    def put(self, request, format=None):

        serializer = user_password_serializer(data=request.data)
        if serializer.is_valid():
            if request.user.check_password(serializer.validated_data[
                                                'old_password']):
                request.user.set_password(serializer.validated_data[
                                          'new_password'])
                request.user.save()

                return Response({'success': True,
                                'result': serializer.validated_data},
                                status=status.HTTP_200_OK)
            else:
                    return Response({'success': False,
                                    'result': "credential mismatch"},
                                    status=status.HTTP_401_UNAUTHORIZED)


        return Response({'success': False,
                        'result': serializer.errors},
                        status=status.HTTP_400_BAD_REQUEST)

I do not wish to change the way an endpoint is constructed. I do have a JWT authenticated call, and I wish /user/password would simply be able to PUT the 'old password' and 'new password' into that very same user.

What am I doing wrong in my generics.UpdateAPIView class? what is that .lookup_field it's talking about?

Upvotes: 3

Views: 1733

Answers (1)

Igonato
Igonato

Reputation: 10806

.lookup_feild is the field (capture group) the UpdateAPIView expects in your url pattern (pk by default), like:

r'^user/(?P<pk>\d+)/password/?$'

However, you should be able to override get_object instead of get_queryset and it should work without any changes to the url.

class user_password(generics.UpdateAPIView):
    authentication_classes = ([JSONWebTokenAuthentication])
    serializer_class = user_password_serializer

    def get_object(self):
        return User.objects.get(id=self.request.user.id)

Also, simply returning self.request.user will work just fine (I don't know how exactly JWT authentication implemented in your project, but most of the time Django pulls the user model in request.user anyway).

Upvotes: 2

Related Questions