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:
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
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
:
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:
DELETE
http: // 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.
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