web-dev-qa-db-fra.com

Supprimer la méthode sur Django Rest Framework ModelViewSet

j'ai essayé de supprimer une seule instance de ManuscriptItem en utilisant Postman pour effectuer mes demandes d'API sur la vue ci-dessous:

class ManuscriptViewSet(viewsets.ModelViewSet):
    """Handles creating, reading and updating items."""

    authentication_classes = (TokenAuthentication,)
    serializer_class = serializers.ManuscriptItemSerializer
    permission_classes = (permissions.PostOwnManuscript, IsAuthenticated,)

    def perform_create(self, serializer):
        """Sets the user profile to the logged in user."""
        serializer.save(author=self.request.user)

    def get_queryset(self):
        """
        This view should return a list of all the manuscripts
        for the currently authenticated user.
        """
        user = self.request.user
        return models.ManuscriptItem.objects.filter(author=user)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def perform_destroy(self, instance):
        instance.delete()

Les fonctions de destruction et d'exécution de destruction sont ce que j'ai tenté sans succès. C'est ce que ça donne quand j'ai essayé:

{"détail": "Méthode \" SUPPRIMER\"non autorisée." }

Voici comment mes URL sont actuellement enregistrées:

router = DefaultRouter()
router.register('manuscripts', views.ManuscriptViewSet, base_name="manuscripts")  # auto basename for models
router.register('manuscriptlibrary', views.ManuscriptLibraryViewSet, base_name="manuscript_library")
router.register('manuscriptsettings', views.ManuscriptSettingsViewSet)


urlpatterns = [
    url(r'', include(router.urls))
]

Je modifie mal le ModelViewSet dois-je utiliser une autre approche en raison de la nature de ModelViewSet? je m'attendais à ce qu'il fonctionne sur Postman lorsque j'utilisais un utilisateur autorisé pour supprimer une instance de ManuscriptItem. Dans les documents, la méthode Destroy () peut être utilisée.

Informations supplémentaires

L'URL utilisée est:

http: // localhost: 8000/manuscripts-api/manuscripts /

L'instance de modèle à supprimer de:

class ManuscriptItem(models.Model):
    """Represents a single manuscript's content"""

    author = models.ForeignKey('accounts_api.UserProfile', on_delete=models.CASCADE)
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=99999999)

    def __str__(self):
        """Django uses when it needs to convert the object to a string"""
        return str(self.id)

La façon dont j'ai essayé d'envoyer des demandes de suppression sur postman avec json:

{
    "manuscript": 7,
}

Résultats: Méthode de suppression non autorisée

{
    "id": 7,
    "author": 5,
    "title": "niceone",
    "content": "niceone"
}

Résultats: Méthode de suppression non autorisée

Questions/informations supplémentaires:

N'ai-je pas besoin de spécifier le registre du routeur avec un pk? J'ai essayé cela mais n'a pas fonctionné non plus:

router.register('manuscripts/{pk}/$', views.ManuscriptViewSet, base_name="manuscript_detail")

Le facteur dit:

Autoriser → GET, POST, HEAD, OPTIONS

7
NewScientists

Le problème ici est que vous envoyez une requête DELETE à la mauvaise URL. Regardez les DefaultRouter docs . Il génère automatiquement vos URL dans votre viewset:

DefaultRouter class url patterns

Examinez attentivement la méthode DELETE. C'est sur le {prefix}/{lookup}/[.format] modèle d'url. Cela signifie que l'URL de votre routeur correspondant est manuscripts/<manuscript_id>/, mais vous essayez d'envoyer DELETE demande à manuscripts/ uniquement, qui est le modèle ci-dessus. Vous voyez directement dans le tableau que les méthodes HTTP autorisées sont GET et POST uniquement. C'est pourquoi vous recevez MethodNotAllowed.

La solution à votre problème est de ne pas passer le manuscript_id en tant que corps JSON de la demande

{
    "manuscript": 7,
}

Mais pour le passer directement à l'url:

DELETEhttp: // localhost: 8000/manuscripts-api/manuscripts/7 /

Et vous enregistrez simplement votre ensemble de vues comme:

router.register(r'manuscripts', ManuscriptViewSet.as_view(), name='manuscripts')

Comme vous le voyez, [~ # ~] drf [~ # ~] génère automatiquement les URL pour vous.

12
wencakisa
def destroy(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
            self.perform_destroy(instance)
        except Http404:
            pass
        return Response(status=status.HTTP_204_NO_CONTENT)

utiliser cela et cela fonctionnera

6
Exprator