Detail": "Method \"GET\" not allowed. | Django Rest Framework

I'm following a course on user login and registration and I'm getting this error and I don't know how to fix it detail": "Method \"GET\" not allowed.

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('users/login/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
    
    path('users/register/', views.registerUser, name='register'),

    path('users/profile/', views.getUserProfile, name="users-profile"),
    path('users/', views.getUsers, name="users"),
]

views.py

@api_view(['POST'])
def registerUser(request):
    data = request.data
    user = User.objects.create(
        first_name = data['name'],
        username = data['email'],
        email = data['email'],
        password = make_password(data['password'])
    )

    serializer = UserSerializerWithToken(user, many=False)

    return Response(serializer.data)

serializers.py

class UserSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField(read_only=True)
    _id = serializers.SerializerMethodField(read_only=True)
    isAdmin = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = User
        fields = ['id', '_id', 'username', 'email', "name", "isAdmin"]

    def get__id(self, obj):
        return obj.id

    def get_isAdmin(self, obj):
        return obj.is_staff
    
    def get_name(self, obj):
        name = obj.first_name
        if name == '':
            name = obj.email

        return name


class UserSerializerWithToken(UserSerializer):
    token = serializers.SerializerMethodField(read_only=True)
    
    class Meta:
        model = User
        fields = ['id', '_id', 'username', 'email', "name", "isAdmin", 'token']

    def get_token(self, obj):
        token = RefreshToken.for_user(obj)
        return str(token.access_token)

I'm not sure if this is the problem but I saw someone who said that since in views.py I have the view as @api_view(['POST']) I cant call it in urls.py the way I usually would. I would test that but I dont know of anyother way to do that

As your api is set to accept only the POST method, you can't simply hit the URL into the browser. api_view(['POST'])

Try to run the API in postman using the POST method

https://www.django-rest-framework.org/api-guide/views/#api_view

or add this

@api_view(['POST', 'GET'])
def registerUser(request):
    if request.method == 'GET':
        return Response({'message': 'In get'})
    data = request.data
    user = User.objects.create(
        first_name = data['name'],
        username = data['email'],
        email = data['email'],
        password = make_password(data['password'])
    )

    serializer = UserSerializerWithToken(user, many=False)

    return Response(serializer.data)

As the error says, your register API should be POST, not GET.

If you call your register API with GET method, the above error occurs.

You can simply test it with curl command (assuming runserver on port 8000).


curl -X GET http://localhost:8000/users/register/ 

this will caouse "Method not allowed" error


curl -d '{"name":"value1", "email":"value2", "password": "value3"}' \
  -X POST http://localhost:8000/users/register/

this will work fine

The default method is GET when we call through the browser. To test these endpoints by giving appropriate methods and data is to use rest API clients like

  1. POSTMAN
  2. Thunder client if your using VS CODE
  3. curl way @fullswing answer, if you want minimal installation

In your api_view you are not using GET method that is the reason it is giving you error. Kindly use GET method also and it should work. Check below for reference

@api_view(['GET','POST'])
def registerUser(request):
     data = request.data
     user = User.objects.create(
     first_name = data['name'],
     username = data['email'],
     email = data['email'],
     password = make_password(data['password'])
 )
Back to Top