已解决:Django:删除请求返回错误 405
Posted
技术标签:
【中文标题】已解决:Django:删除请求返回错误 405【英文标题】:SOLVED: Django: delete requests returning error 405 【发布时间】:2021-03-11 21:57:40 【问题描述】:感谢下面的用户 Roham 解决。问题是我向/api/post/5
发出删除请求时没有尾部斜杠,当我打算让它被path('api/', include(router.urls))
路径捕获时,它落入re_path(r'^(?:.*)/?$', index, name='index')
路径。
将 DELETE 请求更改为 /api/post/5/
并带有斜杠解决了问题,它被 /api 路由捕获,并且任何用于前端的请求都被 re_path
行捕获.
-----------------original post below-----------------
我有一个小型 React/Django 博客应用程序,我正在尝试更改 DELETE 请求的行为。具体来说,我想检查数据库中的帖子是否有一个名为“protected”的字段是否等于真,如果为真则失败。
在此之前的某个时间点,删除帖子效果很好。当我在下面的views.py
中重载PostView
中的destroy
方法时,我注意到它不起作用。 destroy
方法永远不会被调用 - 我从来没有看到里面的 print 语句。服务器以 405 响应并且从不调用 destroy
。这是错误:
Method Not Allowed (DELETE): /api/posts/3
Method Not Allowed: /api/posts/3
[29/Nov/2020 17:03:04] "DELETE /api/posts/3 HTTP/1.1" 405 0
如果我删除我的destroy
方法,它仍然不能像以前那样工作,所以我认为我破坏了一些不相关的东西。我错过了什么?
这是我的urls.py
:
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include, re_path
from rest_framework import routers
from server import views
from .views import index
router = routers.DefaultRouter()
router.register(r'posts', views.PostView, 'post')
urlpatterns = [
path('', index, name='index'),
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
re_path(r'^(?:.*)/?$', index, name='index'),
]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
和views.py
:
from rest_framework import viewsets, status
from .serializers import PostSerializer
from .models import Post
from rest_framework.response import Response
from server.models import Post
class PostView(viewsets.ModelViewSet):
serializer_class = PostSerializer
queryset = Post.objects.all()
def list(self, request):
queryset = Post.objects.all()
serializer = PostSerializer(queryset, many=True)
return Response(serializer.data)
def update(self, request, pk=None):
queryset = Post.objects.all().filter(pk=pk)
post = queryset[0]
if post.protected == False:
post.title = request.data['title']
post.body = request.data['body']
post.save()
return Response("Post updated")
else:
return Response("Post protected", status=status.HTTP_403_FORBIDDEN)
def destroy(self, request, pk=None):
print("In destroy!!!!!!!")
queryset = Post.objects.all().filter(pk=pk)
post = queryset[0]
if post.protected == False:
post.delete()
return Response("Post deleted")
else:
return Response("Post protected", status=status.HTTP_403_FORBIDDEN)
这里是在 React 前端发出删除请求的地方:
axios.delete("/api/posts/" + postId)
.then(post => dispatch(postDeleted(post)))
.then(() => dispatch(fetchPosts()))
.catch(errmess => dispatch(postDeleteFailed(errmess)));
【问题讨论】:
请显示您应用的网址(router.urls) 您好,405 表示服务器不允许这种方法。我认为这很可能与在 DRF 中,某些视图不能采用DELETE
方法的事实有关。看看这个帖子***.com/questions/26711975/…
我看到了那篇文章,但似乎没有任何相关内容。我添加了 CORS_ALLOW_METHODS 列表以明确允许删除,但没有任何变化。上面还有 urls.py 文件 - 这是我在项目中使用的唯一一个。
【参考方案1】:
我认为您的问题是您的 urls
相互覆盖。问题是re_path(r'^(?:.*)/?$', index, name='index')
的正则表达式模式。因此它将您的请求重定向到错误的 url,并且由于该视图不支持 DELETE
方法,它将返回 405
状态代码(不允许使用该方法)。所以你应该删除这个url,或者改变它的正则表达式(因为几乎每个模式都属于它的类别),或者将你的请求url从axios.delete("/api/posts/" + postId)
更改为axios.delete("/api/posts/" + postId + '/')
(你的url应该有斜杠)。我希望这可以解决您的问题。
【讨论】:
有趣的谢谢!就是这样。我把所有的东西都放进去,这样任何其他页面请求都将被定向到前端,以防有人在没有加载前端应用程序的情况下点击了指向 /about.html 页面的链接,例如,它不会被重定向否则到前端。我得想点别的办法。谢谢!以上是关于已解决:Django:删除请求返回错误 405的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django REST Framework 进行身份验证返回 405
DioError [DioErrorType.RESPONSE]: Http 状态错误 [405] [已解决]
在功能齐全的 django 应用程序中测试 POST 时出现 405 错误