web-dev-qa-db-ja.com

Django Rest Frameworkを使用してオブジェクトを削除する方法

Django Rest Frameworkを使用して、イベント計画アプリ用のRESTful APIを記述しようとしていますが、GET HTTPメソッドを予期しないビューを使用すると問題が発生します。チュートリアルを読みましたDjangoサイトのクラスベースビューのドキュメントを読んだ後に理解したことから、このようなクラスベースビューがある場合(DRFチュートリアルから取得) )

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) 

ビュー内のさまざまなメソッドは、さまざまなHTTP要求メソッドに対応しています。だから私がwww.foo.com/barそのアドレスに送信される要求メソッドに基づいて、2つの異なることを行います。つまり、実行される関数はURLの送信に使用されるメソッドに基づいて決定されるため、他に何も指定する必要がないということです。これは正しいです?

DRFサイトの例に基づいてモデル化しようとしたこのビューがあります

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

これらのURLにマップします

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'),

                       )

このコマンドでCURLを使用してテストしようとしています(ここで提案されているように エンコードされたURLでCURLを使用して削除

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

これはそれがすべきことをするようです:

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

しかし、実際のレコードは私のデータベースから削除されません

これを正しく機能させるためにこれらを取得するために忘れていることはありますか?

16
user3282276

あなたは冗長です。 HTTPメソッドはすでにDELETEであるため、URLに/events/deleteはありません。これを試して:

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

デフォルトでは、DRFのルーターは/event/<pk>に詳細なURLを作成し、ユーザーはGETPUTPOSTおよびDELETEを取得、更新、作成しますそれぞれ削除します。

33
Kevin Stone

Kevin Stoneが述べたように、使用するパターンはお勧めできませんが、使用する場合は、URLのevents/delete /マッピングのタイプミスを修正する必要があります。

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

でなければなりません:

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