已解决: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 错误

405 - 未捕获(承诺中)错误:请求失败,状态码为 405

为啥我的 post 请求返回 405 错误? [复制]

django ajax POST 上的 405 错误