Django Rest Framework ModelViewSet 上的删除方法 [英] Delete method on 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 方法只有 GET
和 POST
.这就是您收到 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:
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:
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屋!