Django Rest Framework ModelViewSet 上的删除方法 [英] Delete method on Django Rest Framework ModelViewSet

查看:125
本文介绍了Django Rest Framework ModelViewSet 上的删除方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

class ManuscriptViewSet(viewsets.ModelViewSet):"""处理创建、读取和更新项目."""authentication_classes = (TokenAuthentication,)serializer_class = serializers.ManuscriptItemSerializerpermission_classes = (permissions.PostOwnManuscript, IsAuthenticated,)def perform_create(self, serializer):"""将用户配置文件设置为登录用户."""serializer.save(作者=self.request.user)def get_queryset(self):"""此视图应返回所有手稿的列表对于当前经过身份验证的用户."""用户 = self.request.user返回models.ManuscriptItem.objects.filter(作者=用户)def destroy(self, request, *args, **kwargs):实例 = self.get_object()self.perform_destroy(实例)返回响应(状态=状态.HTTP_204_NO_CONTENT)def perform_destroy(self, instance):实例.删除()

destroy 和 perform destroy 函数是我尝试的,但没有成功.这是我尝试时返回的内容:

<块引用>

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

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

router = DefaultRouter()router.register('manuscripts', views.ManuscriptViewSet, base_name="manuscripts") # 模型的自动basenamerouter.register('manuscriptlibrary', views.ManuscriptLibraryViewSet, base_name="manuscript_library")router.register('manuscriptsettings', views.ManuscriptSettingsViewSet)网址模式 = [url(r'', 包含(router.urls))]

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

其他信息

使用的网址是:

<块引用>

仔细查看 DELETE 方法.它位于 {prefix}/{lookup}/[.format] url 模式中.这意味着您对应的路由器 url 是 manuscripts//,但您尝试仅将 DELETE 请求发送到 manuscripts/,即就是上面的模式.您可以直接从表中看到允许的 HTTP 方法只有 GETPOST.这就是您收到 MethodNotAllowed 的原因.

解决您的问题的方法不是将 manuscript_id 作为请求的 JSON 正文传递

<代码>{手稿":7,}

但是直接传递给url:

<块引用>

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

你只需像这样注册你的视图集:

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

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

i have tried to delete a single ManuscriptItem instance using Postman to perform my API requests on against the view below:

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()

The destroy and perform destroy functions are what I have attempted without success. This is what it returns when i tried:

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

This is how my URLs are currently registered:

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))
]

I'm i modifying the ModelViewSet wrong do i need to use another approach because of the nature of ModelViewSet? i expected it to work on Postman when i used an Authorized user to Delete a ManuscriptItem instance. In the docs it said Destroy() method can be used.

Additional information

The URL used is:

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

The model instance to be deleted from:

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)

The way i have tried sending delete requests on postman with json:

{
    "manuscript": 7,
}

Results: Delete Method not allowed

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

Results: Delete Method not allowed

Additional Questions/Info:

Don't i need to specify the router register with a pk? I tried this but didnt work either:

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

Postman says:

Allow →GET, POST, HEAD, OPTIONS

解决方案

The issue here is that you send DELETE request to the wrong url. Look at the DefaultRouter docs. It generates automatically your urls within your viewset:

Look closely at the DELETE method. It is on the {prefix}/{lookup}/[.format] url pattern. This means that your corresponding router url is manuscripts/<manuscript_id>/, but you try to send DELETE request to manuscripts/ only, which is the above pattern. You see directly from the table that the allowed HTTP methods there are GET and POST only. That's why you receive MethodNotAllowed.

The solution to your problem is not to pass the manuscript_id as a JSON body of the request

{
    "manuscript": 7,
}

But to pass it directly to the url:

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

And you just register your viewset like:

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

As you see, DRF generates the urls automatically for you.

这篇关于Django Rest Framework ModelViewSet 上的删除方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆