"detail": "Method \"GET\" not allowed." Django Rest Framework

18,892

Solution 1

You need to add GET endpoint url to your urls.py in order to use GET requests. GET url is missing in your urls.py, simply edit your urls.py like:

# urls.py

from django.urls import include, path
from classroom.views.classroom import current_user, UserList
from .views import classroom, suppliers, teachers

urlpatterns = [
               path('', classroom.home, name='home'),
               path('current_user/', current_user),
               path('users/', UserList.as_view()),
               path('users/<int:pk>/', UserList.as_view()),
              ]

And you need to implement get method in yourUserList view such as:

# views.py

class UserList(APIView):
    """
    Create a new user. It's called 'UserList' because normally we'd have a get
    method here too, for retrieving a list of all User objects.
    """

    permission_classes = (permissions.AllowAny,)
    http_method_names = ['get', 'head']


    def get(self, request, format=None):
        users = User.objects.all()
        serializer = UserSerializerWithToken(users, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        self.http_method_names.append("GET")

        serializer = UserSerializerWithToken(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Solution 2

I had the same issue but I noticed that in my views.py, I had

renderer_class = api_settings.DEFAULT_RENDERER_CLASSES

I corrected it to :

renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES 

and it worked for me.

Solution 3

Basically the problem is that, there is not functionality defined for GET requests in your view. So either you can add it, like this:

class UserList(APIView):
    permission_classes = (permissions.AllowAny,)
    http_method_names = ['get', 'head', 'post']

    def get(self, request, *args, **kwargs):
        serializer = UserSerializerWithToken(User.objects.all(), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post (self, request, format=None):
        self.http_method_names.append("GET")
        serializer = UserSerializerWithToken(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Or you can subclass UserList View from ListAPIView.

FYI, permission_classes won't work with APIView. You need to use GenericAPIView or any other generic views to have those functionalities.

Share:
18,892
Rohit Kumar
Author by

Rohit Kumar

Updated on July 07, 2022

Comments

  • Rohit Kumar
    Rohit Kumar almost 2 years

    I know this question maybe a duplicate, but I have tried many solutions and could not understand any. I have followed this tutorial exactly and yet I get this error on the 'userlist' page. Everything else works just fine. Can somebody point out what the error is ?

    class UserList(APIView):
    """
    Create a new user. It's called 'UserList' because normally we'd have a get
    method here too, for retrieving a list of all User objects.
    """
    
    permission_classes = (permissions.AllowAny,)
    http_method_names = ['get', 'head']
    
    def post (self, request, format=None):
        self.http_method_names.append("GET")
    
        serializer = UserSerializerWithToken(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    EDIT: urls.py

    from django.urls import include, path
    from classroom.views.classroom import current_user, UserList
    from .views import classroom, suppliers, teachers
    urlpatterns = [path('', classroom.home, name='home'),
                   path('current_user/', current_user),
                   path('users/', UserList.as_view()),
    

    Edit:

    Still getting this error,

    err

  • Rohit Kumar
    Rohit Kumar almost 5 years
    But you never changed the function UserList to accept pk ?? How can this work ?
  • Rohit Kumar
    Rohit Kumar almost 5 years
    Oh, I did not realize that. But, I am still getting that error. I do not understand by reading the tutorial I am following, what exaclty is the purpose of this 'users' page ?
  • Rohit Kumar
    Rohit Kumar almost 5 years
    I get an error at this line serializer = UserSerializerWithToken(queryset=User.objects.all(), many=True) . Error is TypeError at /users/
  • Rohit Kumar
    Rohit Kumar almost 5 years
    TypeError at /users/ __init__() got an unexpected keyword argument 'queryset' Request Method: GET Request URL: http://127.0.0.1:8000/users/ Django Version: 2.0.1 Exception Type: TypeError Exception Value: __init__() got an unexpected keyword argument 'queryset' Exception Location: C:\Users\idadarklord\AppData\Local\Programs\Python‌​\Python37\lib\site-p‌​ackages\rest_framewo‌​rk\serializers.py in __init__, line 117
  • ruddra
    ruddra almost 5 years
    Oh, I made a mistake in code. Updated my answer. :)
  • Rohit Kumar
    Rohit Kumar almost 5 years
    Thanks a lot! Can you maybe explain a little what was going wrong ?
  • cagrias
    cagrias almost 5 years
    To allow using GET requests, you simply need to implement get method in APIView. When asking your question, you had only implemented post method, that's why you couldn't use GET method. django-rest-framework.org/tutorial/3-class-based-views is a good document to follow.