Django Rest FrameworkModelViewSetのメソッドを削除します

Source django django-models django-rest-framework django-views

以下のビューに対して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()

破棄および破棄機能の実行は、私が成功せずに試みたものです。これは私が試したときに返されるものです:

{ "detail": "Method \"DELETE\" not allowed." }



これが私の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を間違って変更していますが、ModelViewSetの性質上、別のアプローチを使用する必要がありますか?許可されたユーザーを使用してManuscriptItemインスタンスを削除したときに、Postmanで機能することを期待していました。ドキュメントでは、Destroy()メソッドを使用できると書かれています。

追加情報

使用されるURLは次のとおりです。

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



削除するモデルインスタンス:
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")

郵便配達員は言う:

Allow →GET, POST, HEAD, OPTIONS

推奨答え
ここでの問題は、DELETEリクエストを間違ったURLに送信することです。 DefaultRouter docsを見てください。それはあなたのviewset内にあなたのURLを自動的に生成します:

DefaultRouter class url patterns
DELETEメソッドをよく見てください。 {prefix}/{lookup}/[.format]のURLパターンにあります。これは、対応するルーターのURLがmanuscripts/<manuscript_id>/であることを意味しますが、DELETEリクエストをmanuscripts/にのみ送信しようとします。これは、上記のパターンです。表から直接、許可されているHTTPメソッドにはGETPOSTのみがあることがわかります。そのため、MethodNotAllowedを受け取ります。

問題の解決策は、リクエストのJSON本文としてmanuscript_idを渡さないことです。
{
    "manuscript": 7,
}

しかし、それをURLに直接渡すには:

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



そして、次のようにビューセットを登録するだけです。
router.register(r'manuscripts', ManuscriptViewSet.as_view(), name='manuscripts')

ご覧のとおり、 DRFはURLを自動的に生成します。
その他答え #1
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)

これを使用すると動作します

関連記事

GridSearchCVでテスト/トレインセットを明示的に指定する
Clipboardとの間でコピーすると、画像transparencyが失われます。
DjangoTemplateResponseとレンダリング
Djangoajaxエラー応答のベストプラクティス
DjangoモデルとPythonプロパティ