web-dev-qa-db-fra.com

Comment supprimer un objet en utilisant Django Rest Framework

J'essaie d'écrire une API RESTful pour mon application de planification d'événements en utilisant Django Rest Framework mais j'ai des problèmes lors de l'utilisation de vues qui n'attendent pas la méthode HTTP GET. J'ai lu le didacticiel sur le site DRF. D'après ce que je comprends après avoir lu le didacticiel et la documentation de la vue basée sur la classe sur le site Django, c'est que s'il existe une vue basée sur la classe comme celle-ci (tirée du didacticiel 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) 

Les différentes méthodes de la vue correspondent aux différentes méthodes de requête HTTP. Donc, si j'ai www.foo.com/bar cela ferait deux choses différentes selon la méthode de requête envoyée à cette adresse. Cela signifie donc que je n'aurais rien d'autre à spécifier car la fonction exécutée est déterminée en fonction de la méthode avec laquelle l'URL est envoyée. Est-ce correct?

J'ai cette vue que j'ai essayé de modéliser d'après l'exemple sur le site 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

qui correspond à ces 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'),

                       )

que j'essaie de tester en utilisant CURL avec cette commande (comme suggéré ici SUPPRIMER en utilisant CURL avec URL encodée )

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

Cela semblera faire ce qu'il faut:

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

Mais l'enregistrement réel n'est pas supprimé de ma base de données

Y a-t-il quelque chose ici que j'oublie de faire pour les faire fonctionner correctement?

16
user3282276

Tu es redondant. La méthode HTTP est déjà DELETE, il n'y a donc pas de /events/delete dans l'url. Essaye ça:

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

Par défaut, le routeur de DRF crée des URL détaillées à /event/<pk> et vous GET, PUT, POST et DELETE pour les récupérer, mettre à jour, créer et supprimer respectivement.

33
Kevin Stone

Comme mentionné par Kevin Stone, le modèle que vous utilisez n'est pas recommandé, mais si vous souhaitez l'utiliser, vous devrez corriger la faute de frappe dans vos URL pour le mappage events/delete / .

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

devrait être:

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