在Django Rest Framework ModelViewSet上删除方法

New*_*sts 3 django django-models django-views django-rest-framework

我试图使用Postman删除单个ManuscriptItem实例,以针对以下视图执行我的API请求:

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()
Run Code Online (Sandbox Code Playgroud)

破坏和执行破坏功能是我没有成功的尝试.这是我尝试时返回的内容:

{"detail":"方法"DELETE \"不允许." }

这就是我的网址目前注册的方式:

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))
]
Run Code Online (Sandbox Code Playgroud)

我正在修改ModelViewSet错误我需要使用另一种方法,因为ModelViewSet的性质?当我使用授权用户删除ManuscriptItem实例时,我希望它可以在Postman上工作.在文档中它表示可以使用Destroy()方法.

附加信息

使用的URL是:

HTTP://本地主机:8000 /手稿-API /手稿/

要删除的模型实例:

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)
Run Code Online (Sandbox Code Playgroud)

我尝试使用json在postman上发送删除请求的方式:

{
    "manuscript": 7,
}
Run Code Online (Sandbox Code Playgroud)

结果:不允许删除方法

{
    "id": 7,
    "author": 5,
    "title": "niceone",
    "content": "niceone"
}
Run Code Online (Sandbox Code Playgroud)

结果:不允许删除方法

其他问题/信息:

我不需要用pk指定路由器寄存器吗?我尝试了这个,但也没有工作:

router.register('manuscripts/{pk}/$', views.ManuscriptViewSet, base_name="manuscript_detail")
Run Code Online (Sandbox Code Playgroud)

邮递员说:

允许→GET,POST,HEAD,OPTIONS

wen*_*isa 11

这里的问题是您将DELETE请求发送到错误的URL.看看DefaultRouter文档.它会自动生成您的网址viewset:

DefaultRouter类url模式

仔细看看这个DELETE方法.它在{prefix}/{lookup}/[.format]网址模式上.这意味着您的相应路由器URL是manuscripts/<manuscript_id>/,但您尝试仅发送DELETE请求manuscripts/,这是上述模式.您可以直接看到从允许的HTTP方法有桌子GETPOST唯一的.这就是你收到的原因MethodNotAllowed.

您的问题的解决方案不是传递manuscript_id作为请求的JSON主体

{
    "manuscript": 7,
}
Run Code Online (Sandbox Code Playgroud)

但是要将它直接传递给url:

DELETE HTTP://本地主机:8000 /手稿-API /手稿/ 7 /

你只需注册你的视图集:

router.register(r'manuscripts', ManuscriptViewSet.as_view(), name='manuscripts')
Run Code Online (Sandbox Code Playgroud)

如您所见,DRF会自动为您生成网址.


Exp*_*tor 5

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)
Run Code Online (Sandbox Code Playgroud)

使用它,它会工作