27

I am trying to write an RESTful API for my event planning app using Django Rest Framework but I am having some trouble when using views that do not expect the GET HTTP method. I have read through the tutorial on the DRF site. From what I understand after reading through the tutorial and the class based view documentation on the Django site is that if there is a class based view like this (taken from the DRF tutorial)

class SnippetDetail(APIView):
    """
    Retrieve, update or delete a snippet instance.
    """
    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT) 

The different methods in the view correspond to the different HTTP Request methods. So if I have www.foo.com/bar it would do two different things based on what request method is sent to that address. So that means that I wouldn't have to specify anything else because the function that is executed is determined based on the method the URL is sent with. Is this correct?

I have this view which I tried to model after the example on the DRF site

class EventDetail(APIView):

    """
    Retrieve, update or delete a event instance.
    """

    def get_object(self, pk):
        try:
            return Event.objects.get(pk=pk)
        except Event.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        event = self.get_object(pk)
        serializer = EventSerializer(event)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = EventSerializer(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)

    # def put(self, request, pk, format=None):
    #     event = self.get_object(pk)
    #     serializer = EventSerializer(event, data=request.DATA)
    #     if serializer.is_valid():
    #         serializer.save()
    #         return Response(serializer.data)
    #     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        event = self.get_object(pk)
        event.delete()
        return Response(status=status.HTTP_204_NO_CONTENT

which maps to these URLs

urlpatterns = patterns('',

                       # Get event
                       url(r'^(?P<pk>\d+)/$', views.EventDetail.as_view(),
                           name='create_events'),
                       # list all events
                       url(r'^list/$', views.EventList.as_view(),
                           name='list_events'),
                       # url(r'^update$/(?P<pk>\d+)', #update event),
                       url(r'^create/$', views.EventDetail.as_view(),
                           name='create_events'),
                       # delete event
                       url(r'^delete$/(?P<pk>\d+)',
                           views.EventDetail.as_view(), name='delete_event'),

                       )

which I am trying to test using CURL with this command (like suggested here DELETE using CURL with encoded URL)

curl -X DELETE "http://127.0.0.1:8000/events/delete/1"

This will seem to do what it should:

[18/Oct/2014 22:41:27] "DELETE /events/delete/1 HTTP/1.1" 404 2707

But the actual record is not deleted from my database

Is there something here that I am forgetting to do to get these to get this to work properly?

2 Answers 2

47

You're being redundant. The HTTP method is already DELETE, so there's no /events/delete in the url. Try this:

curl -X DELETE "http://127.0.0.1:8000/events/1/"

By default, DRF's router creates detailed urls at /event/<pk> and you GET, PUT, POST and DELETE them to retrieve, update, create and delete respectively.

Sign up to request clarification or add additional context in comments.

4 Comments

But what about me mapping /events/delete in the URLConfs?
Not advised (it's kind of anti-REST), but you'd setup your urlconf to add url(r'/events/delete/(?P<pk>\d+)', EventDetail.as_view())
That is what I have in my urlconf currently. Shouldn't it be working with the address I specified already? But from what you are saying I'll change it to be more Restful thanks for the answer
See Steven Laroche's answer below. You had a misplaced $ in your urlconf (it signals the end of of the line, so can't appear in the middle of your url pattern.
2

As mentioned by Kevin Stone, the pattern you're using isn't advisable, but if you want to use it, you'll need to fix the typo in your urls for the events/delete/ mapping.

 # delete event
 url(r'^delete$/(?P<pk>\d+)',
     views.EventDetail.as_view(), name='delete_event'),

should be:

 # delete event
 url(r'^delete/(?P<pk>\d+)',
     views.EventDetail.as_view(), name='delete_event'),

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.