以下のビューに対してAPIリクエストを実行するためにPostmanを使用して単一のManuscriptItemインスタンスを削除しようとしました:
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()
Destroy関数とdestroy関数の実行は、成功せずに試みたものです。これは私が試したときに返されるものです:
{"detail": "メソッド\" DELETE\"は許可されていません。" }
これが私のURLが現在登録されている方法です:
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))
]
ModelViewSetの性質上、別の方法を使用する必要がありますか?許可されたユーザーを使用してManuscriptItemインスタンスを削除すると、Postmanで機能することが期待されました。ドキュメントでは、Destroy()メソッドを使用できると述べています。
追加情報
使用されるURLは次のとおりです。
削除するモデルインスタンス:
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)
私がjsonでpostmanに削除リクエストを送信しようとした方法:
{ "manuscript": 7, }
結果:削除メソッドは許可されていません
{ "id": 7, "author": 5, "title": "niceone", "content": "niceone" }
結果:削除メソッドは許可されていません
追加の質問/情報:
ルーターレジスタをpkで指定する必要はありませんか?私はこれを試しましたが、どちらもうまくいきませんでした:
router.register('manuscripts/{pk}/$', views.ManuscriptViewSet, base_name="manuscript_detail")
郵便配達さんのコメント:
許可→GET、POST、HEAD、OPTIONS
ここでの問題は、DELETE
リクエストを間違ったURLに送信することです。 DefaultRouter
docs を見てください。 viewset
内にURLを自動的に生成します:
DELETE
メソッドをよく見てください。 {prefix}/{lookup}/[.format]
urlパターン上にあります。つまり、対応するルーターのURLはmanuscripts/<manuscript_id>/
ですが、DELETE
リクエストをmanuscripts/
のみに送信しようとすると、上記のパターンになります。許可されているHTTPメソッドはGET
とPOST
のみであることが表から直接わかります。これがMethodNotAllowed
を受け取る理由です。
問題の解決策は、manuscript_id
をリクエストのJSONボディとして渡さないことです
{
"manuscript": 7,
}
しかし、それを直接urlに渡すには:
DELETE
http:// localhost:8000/manuscripts-api/manuscripts/7 /
そして、あなたはあなたのビューセットを次のように登録するだけです:
router.register(r'manuscripts', ManuscriptViewSet.as_view(), name='manuscripts')
ご覧のとおり、[〜#〜] drf [〜#〜]は自動的にURLを生成します。
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)
これを使うとうまくいきます