django rest post返回405错误代码

django rest post返回405错误代码,django,django-rest-framework,Django,Django Rest Framework,我将django与rest框架一起使用,我尝试在现有对象上测试POST,但我一直得到405。我的视图集如下所示: class Agents(viewsets.ModelViewSet): serializer_class = serializer.AgentSerializer model = serializer_class.Meta.model .... response = self.client.post(url, {'available': True, 'on

我将django与rest框架一起使用,我尝试在现有对象上测试POST,但我一直得到405。我的视图集如下所示:

class Agents(viewsets.ModelViewSet):
    serializer_class = serializer.AgentSerializer
    model = serializer_class.Meta.model
    ....
response = self.client.post(url, {'available': True, 'online':True}, format='json')
在URL中:

router = routers.SimpleRouter()
router.register(r'rest/agents', api_views.Agents, "Agent")
...
urlpatterns += router.urls
我从APITestCase类(rest测试)中调用post请求,我的post请求如下所示:

class Agents(viewsets.ModelViewSet):
    serializer_class = serializer.AgentSerializer
    model = serializer_class.Meta.model
    ....
response = self.client.post(url, {'available': True, 'online':True}, format='json')
打印url显示“/chat/rest/agents/1910_1567/”,而1910_1567是现有代理的有效id(我在安装过程中创建代理并使用其id)

我已经看到了关于RESTPOST获取405的其他问题,但是所有的解决方案都与url相关,在我的例子中,url是正确的。我甚至在测试之外运行了设置,并通过浏览器访问了url,以获得对象和对象确实存在。但是当我试着发到405的时候

有什么想法吗


谢谢

最可能的情况是,您的url与某个不同url的正则表达式相匹配,并且请求被发送到另一个不允许post请求的视图。你能在你的URL.py中提到其他URL吗?实际上,您可以通过在视图的分派方法中添加pdb(调试器)来验证这一点。如果你到了pdb,那么你可以认为我错了

如果不是这样,则可以使用调试器从dispatch方法计算问题。以防万一你对怎么做有任何疑问-

class Agents(viewsets.ModelViewSet):
     serializer_class = serializer.AgentSerializer
     model = serializer_class.Meta.model

     def dispatch(self, *args, **kwargs):
         import ipdb; ipdb.set_trace()
         return super(Agents, self).dispatch(*args, **kwargs)
找到的解决方案:-


您正在url中传递id,所以此请求将被路由到详细视图,而详细视图只允许对资源执行GET、PUT和DELETE操作,因为资源已经存在。因此,要创建资源,请不要提供id。否则,请使用PUT请求并提供对PUT中创建的支持。

最可能的情况是,您的url以某种方式与某个不同url的正则表达式匹配,并且请求被发送到不允许post请求的其他视图。你能在你的URL.py中提到其他URL吗?实际上,您可以通过在视图的分派方法中添加pdb(调试器)来验证这一点。如果你到了pdb,那么你可以认为我错了

如果不是这样,则可以使用调试器从dispatch方法计算问题。以防万一你对怎么做有任何疑问-

class Agents(viewsets.ModelViewSet):
     serializer_class = serializer.AgentSerializer
     model = serializer_class.Meta.model

     def dispatch(self, *args, **kwargs):
         import ipdb; ipdb.set_trace()
         return super(Agents, self).dispatch(*args, **kwargs)
找到的解决方案:-


您正在url中传递id,所以此请求将被路由到详细视图,而详细视图只允许对资源执行GET、PUT和DELETE操作,因为资源已经存在。因此,要创建资源,请不要提供id。否则,请使用PUT请求并为PUT中的创建提供支持。

POST应该用于创建目的。如果要使用视图集进行更新,则需要放置或修补(部分更新)

编辑: 有关这方面的更多信息,下面是有关REST API使用的HTTP方法的一些解释:

DRF文档中也描述了这一点:
帖子应该是为了创作目的。如果要使用视图集进行更新,则需要放置或修补(部分更新)

编辑: 有关这方面的更多信息,下面是有关REST API使用的HTTP方法的一些解释:

DRF文档中也描述了这一点:

PS我认为这很明显,但当我重写update()函数并添加print时,print永远不会被调用,例如,我不是从update的实现中得到405,而是在这之前得到的。看起来确实与url相关,但我验证了url及其ok:/尾随斜杠应该在那里吗?如果您设置
router=SimpleRouter(trailing\u slash=False)
,@Railslide post URL通常以trailing slash结尾,但我尝试了您的建议并得到了相同的结果。如果您卷曲到它呢?@Railslide我不明白-您所说的“卷曲到它”是什么意思?谢谢:)PS我认为这很明显,但是当我重写update()函数并添加print时,print永远不会被调用,例如我不是从update的实现中得到405,而是在那之前。看起来确实与url相关,但我验证了url及其ok:/尾随斜杠应该在那里吗?如果您设置
router=SimpleRouter(trailing\u slash=False)
,@Railslide post URL通常以trailing slash结尾,但我尝试了您的建议并得到了相同的结果。如果您卷曲到它呢?@Railslide我不明白-您所说的“卷曲到它”是什么意思?谢谢:)谢谢你和她,但这不是问题所在。命名空间“/chat/rest”对于这个对象api是唯一的,只是为了确保我在上面一行添加了对同一url的get()调用,并且它可以正常工作并返回代理对象。(我不想发布URL,因为它有点长,我不想在问题中添加“噪音”)谢谢你的调试示例!我调试了调度,发现ViewSet对象没有post方法!由于这一行,它返回405:handler=getattr(self,request.method.lower(),self.http\u method\u not\u允许),其中request.method确实是post。如果我使用ViewSet.ModelViewSet,为什么我的视图集中没有post?你知道这有什么意义吗?谢谢!:)它是只在测试中发生还是也在浏览器中发生?在浏览器中,使用rest框架默认视图,我得到了“详细信息”:“不允许使用方法\”POST \“。编辑:我在标题数据中看到“允许:获取、放置、修补、头部、选项”,一旦我将post()方法添加到我的ViewSet对象并刷新,“post”就会添加到允许列表中。这是有道理的,但是应该为ModelViewSet自动创建post(),不是吗?谢谢hspandher,但这不是问题所在。命名空间“/chat/rest”对于这个对象api是唯一的,只是为了确保我在上面一行添加了对同一url的get()调用,并且它可以正常工作并返回代理对象。(我不想发布URL,因为它有点长,我不想在问题中添加“噪音”)谢谢你的调试示例!我调试了调度,发现ViewSet对象没有post方法!由于这一行,它返回405:handler=getattr(self,request.method.lower(),self.http\u method\u not\u允许),其中request.method确实是post。所以