pythondjangoreact-nativejwtdjango-rest-framework-jwt

"Method \"GET\" not allowed." Django


my views.py file:

from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import UserSerializer


class TestView(APIView):
    def get(self, request, format=None):
        print("API called")
        return Response("You did it!", status=200)


class UserView(APIView):
    def post(self, request, format=None):
        print("User created")

        user_data = request.data
        print(request.data)
        user_serializer = UserSerializer(data=user_data)

        if user_serializer.is_valid(raise_exception=False):
            user_serializer.save()
            return Response({'user': user_serializer.data}, status=200)

        return Response({'msg': "error: no user created"}, status=400)

# convert user token to user data


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

    if request.user.is_authenticated == False or request.user.is_active == False:
        return Response('Invalid credentials', status=403)

    user = UserSerializer(request.user)
    print(user.data)

    return Response("Testing", status=200)

my serializers.py file:

from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.validators import UniqueValidator
from rest_framework.settings import api_settings


class UserSerializer(serializers.ModelSerializer):

    token = serializers.SerializerMethodField()

    email = serializers.EmailField(
        required=True,
        validators=[UniqueValidator(queryset=User.objects.all())]
    )

    username = serializers.CharField(
        required=True,
        max_length=32,
        validators=[UniqueValidator(queryset=User.objects.all())]
    )

    first_name = serializers.CharField(
        required=True,
        max_length=32
    )

    last_name = serializers.CharField(
        required=True,
        max_length=32
    )

    password = serializers.CharField(
        required=True,
        min_length=8,
        write_only=True
    )

    def create(self, validated_data):
        password = validated_data.pop(password, None)
        instance = self.Meta.model(**validated_data)
        if password is not None:
            instance.set_password(password)
        instance.save()
        return instance

    def get_token(self, obj):
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(obj)
        token = jwt_encode_handler(payload)
        return token

    class Meta:
        model = User
        fields = (
            'token',
            'username',
            'password',
            'first_name',
            'last_name',
            'email',
            'id'
        )

my urls.py file:

from django.urls import path
from .views import TestView, UserView
from rest_framework_jwt.views import refresh_jwt_token, verify_jwt_token

urlpatterns = [
    path('test', TestView.as_view()),
    path('create-user/', UserView.as_view()),
    path('get-user', UserView.as_view()),
]

I've created a user and they're successfully store my SQLite database. Now, I want to fetch the user using their token. So I've created a GET method in views.py and added a get-user URL to the urls.py file.

The Postman request:

enter image description here

As you can see, I'm sending JWT {token} as a header under "Authorization." However, I get GET method not allowed. I'm confused as to what's wrong.

What appears on my CMD when I send the request:

enter image description here


Solution

  • Not sure if its a typo but you have the get method outside of the UserView class in the code block.

    And another thing, there is no need to use two different endpoints for the same APIView, just send a get request to create-user endpoint or better yet just use a ModelViewSet instead, since you're already using a ModelSerializer.