如何使用 Django Rest Framework 删除对象
Posted
技术标签:
【中文标题】如何使用 Django Rest Framework 删除对象【英文标题】:How to delete an object using Django Rest Framework 【发布时间】:2014-12-14 05:50:03 【问题描述】:我正在尝试使用 Django Rest Framework 为我的活动计划应用程序编写一个 RESTful API,但是在使用不期望 GET HTTP 方法的视图时遇到了一些问题。我已经阅读了 DRF 网站上的教程。根据我在阅读教程和 Django 站点上基于类的视图文档后的理解,如果有这样的基于类的视图(取自 DRF 教程)
class SnippetDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, pk):
try:
return Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
def put(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet, data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
视图中不同的方法对应不同的HTTP Request方法。因此,如果我有www.foo.com/bar
,它将根据发送到该地址的请求方法做两件不同的事情。所以这意味着我不必指定任何其他内容,因为执行的函数是根据发送 URL 的方法确定的。这是正确的吗?
我有这个视图,我试图模仿 DRF 网站上的示例
class EventDetail(APIView):
"""
Retrieve, update or delete a event instance.
"""
def get_object(self, pk):
try:
return Event.objects.get(pk=pk)
except Event.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
event = self.get_object(pk)
serializer = EventSerializer(event)
return Response(serializer.data)
def post(self, request, format=None):
serializer = EventSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def put(self, request, pk, format=None):
# event = self.get_object(pk)
# serializer = EventSerializer(event, data=request.DATA)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
event = self.get_object(pk)
event.delete()
return Response(status=status.HTTP_204_NO_CONTENT
映射到这些 URL
urlpatterns = patterns('',
# Get event
url(r'^(?P<pk>\d+)/$', views.EventDetail.as_view(),
name='create_events'),
# list all events
url(r'^list/$', views.EventList.as_view(),
name='list_events'),
# url(r'^update$/(?P<pk>\d+)', #update event),
url(r'^create/$', views.EventDetail.as_view(),
name='create_events'),
# delete event
url(r'^delete$/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),
)
我正在尝试使用带有此命令的 CURL 进行测试(如此处建议的 DELETE using CURL with encoded URL)
curl -X DELETE "http://127.0.0.1:8000/events/delete/1"
这似乎会做它应该做的:
[18/Oct/2014 22:41:27] "DELETE /events/delete/1 HTTP/1.1" 404 2707
但实际记录并没有从我的数据库中删除
这里有什么我忘记做的事情来让它们正常工作吗?
【问题讨论】:
【参考方案1】:你是多余的。 HTTP方法已经是DELETE
,所以url中没有/events/delete
。试试这个:
curl -X DELETE "http://127.0.0.1:8000/events/1/"
默认情况下,DRF的路由器会在/event/<pk>
创建详细的url,而你GET
、PUT
、POST
和DELETE
分别对它们进行检索、更新、创建和删除。
【讨论】:
但是我在 URLConfs 中映射 /events/delete 呢? 不建议(这是一种反 REST),但您需要设置 urlconf 以添加url(r'/events/delete/(?P<pk>\d+)', EventDetail.as_view())
这就是我目前在我的 urlconf 中的内容。它不应该与我已经指定的地址一起使用吗?但从你所说的我会把它改成更安静的谢谢你的回答
见下面 Steven Laroche 的回答。您的 urlconf 中有一个错误的 $
(它表示行尾,因此不能出现在您的 url 模式的中间。【参考方案2】:
正如 Kevin Stone 所提到的,您使用的模式是不可取的,但如果您想使用它,您需要修复 events/delete/ 的 URL 中的拼写错误 em> 映射。
# delete event
url(r'^delete$/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),
应该是:
# delete event
url(r'^delete/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),
【讨论】:
感谢您澄清我完全忽略了 $以上是关于如何使用 Django Rest Framework 删除对象的主要内容,如果未能解决你的问题,请参考以下文章
django.test.client 上的 Django rest 框架导入错误
无法使用 Django Rest 框架发送压缩的 gzip 数据
Django REST to React - 无需密码即可获取社交身份验证令牌
尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应