"detail": "Method \"GET\" not allowed. on calling endpoint in django

14,576

Solution 1

The Method not allowed error is because, it searches for a get() method inside your API class, and it couldn't find a one.
The general format of the API class is as below

class LocationView(views.APIView):
    def get(self, request):
        #do something with 'GET' method
        return Response("some data")

    def post(self, request):
        #do something with 'POST' method
        return Response("some data")


If you want to invoke the get_or_create() method at some point, you can do it as any other methods,

class LocationView(views.APIView):
    def get_or_create(self, request):
        # do some "get or create" stuff
        return "some data"

    def get(self, request):
        if condition:
            self.get_or_create(request)
            # do some stuff
            return Response(" some special data related to get or create")
        return Response("some data")

Solution 2

You need to provide separate methods for get and post. If your get method also creates an instance, then you can just call your current get_or_create inside both get and post methods.

class LocationView(views.APIView):

    def get_or_create(self, request):
        # your current definition here

    def get(self, request):
       return self.get_or_create(request)

    def post(self, request):
       return self.get_or_create(request)

Solution 3

For my situation, I was sending a request properly as my view would expect, a POST. But the issue was on http/s. I had set a permanent redirect, from http to https on my app, and so sending a POST to the http version resulted in a GET somehow when the server was redirecting.

TL;DR

HTTP instead of HTTPS

Share:
14,576
Melissa Stewart
Author by

Melissa Stewart

Updated on July 02, 2022

Comments

  • Melissa Stewart
    Melissa Stewart almost 2 years

    I'm using django.rest_framework. I have a get_or_create method for a particular view,

    class LocationView(views.APIView):
        def get_or_create(self, request):
            try:
                location = Location.objects.get(country=request.data.get("country"), city=request.data.get("city"))
                Response(location, status=status.HTTP_200_OK)
            except Location.DoesNotExist:
                serializer = LocationSerializer(data=request.data)
                if serializer.is_valid():
                    serializer.save()
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    This is the location Model,

    class Location(models.Model):
        country = models.CharField(max_length=255)
        city = models.CharField(max_length=255, unique=True)
        latitude = models.CharField(max_length=255)
        longitude = models.CharField(max_length=255)
    
        class Meta:
            unique_together = ('country', 'city')
    

    This is my url,

    url(r'^location/$', LocationView.as_view(), name='location'),
    

    When I call this endpoint in the following way, http://127.0.0.1:8000/api/v1/bouncer/location/?country=USA&&city=Sunnyvale&&latitude=122.0363&&longitude=37.3688

    This is what I get,

    {
        "detail": "Method \"GET\" not allowed."
    }
    

    What am I missing here.

  • Melissa Stewart
    Melissa Stewart about 6 years
    Couldn you provide a little code example from my existing code. That will help understanding.
  • Lorenzo Peña
    Lorenzo Peña about 6 years
    I'd also suggest you take a look at the default Manager.get_or_create Django provides, so you don't have to do the logic yourself inside the try except docs.djangoproject.com/en/2.0/ref/models/querysets/…