djangodjango-rest-frameworkputhttp-errordjango-generic-views

put method not working on RetrieveUpdateDestroyAPIView Django Rest Framework Angular


I am attempting to make a put request in django rest framework. My view is inheriting from the RetrieveUpdateDestroyAPIView class.

I am using angular on the front end django rest on the back end.

Here is the error:

Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
ERROR 
detail:"Method "PUT" not allowed."

Here is the full implementation of the put request from angular side to django rest

editcity(index){
    this.oldcityname = this.cities[index].city;
     const payload = {
      citypk: this.cities[index].pk,
      cityname: this.editcityform.form.value.editcityinput
    };
     this.suitsettingsservice.editcity(payload, payload.citypk)
       .subscribe(
         (req: any)=>{
           this.cities[index].city = req.city;
           this.editcitysucess = true;
           // will have changed
           this.newcityname = this.cities[index].city;
         }
       );
  }

the service being called

editcity(body, pk){
    const url = suitsettingscity + '/' + pk;
    return this.http.put(url, body);

the url being mapped django side:

url(r'^city/(?P<pk>[0-9]+)',SearchCityDetail.as_view())

the view class

class SearchCityDetail(RetrieveUpdateDestroyAPIView):
    queryset = SearchCity.objects.all()
    serializer_class = SearchCitySerializer

the RetrieveUPdateDestoryAPIView documentation:

http://www.django-rest-framework.org/api-guide/generic-views/#updatemodelmixin

RetrieveUpdateDestroyAPIView Used for read-write-delete endpoints to represent a single model instance.

Provides get, put, patch and delete method handlers.

Extends: GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

The RetrieveUpdateDestroyAPIView source code:

class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                   mixins.UpdateModelMixin,
                                   mixins.DestroyModelMixin,
                                   GenericAPIView):
    """
    Concrete view for retrieving, updating or deleting a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

Solution

  • Your URL pattern for the SearchCityListCreate was matching /city/x/ so your request was being handled by the wrong view.

    You fixed the problem by switching the order, but a better fix is to make sure your regexes have ^ and $ to mark the beginning and end of the URL respectively.

    url(r'^city$', SearchCityListCreate.as_view()),
    url(r'^city/(?P<pk>[0-9]+)$',SearchCityDetail.as_view()),