2015-06-16 26 views
1

我使用與休息框架Django和我嘗試測試POST現有的對象,但我不斷收到405我的視圖集中看起來是這樣的:Django的休息後返回405錯誤代碼

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

,並在網址:

router = routers.SimpleRouter() 
router.register(r'rest/agents', api_views.Agents, "Agent") 
... 
urlpatterns += router.urls 

我所說的POST請求從APITestCase類(靜態測試)中,我的POST請求是這樣的:

response = self.client.post(url, {'available': True, 'online':True}, format='json') 

和打印網址顯示「/ chat/rest/agents/1910_1567 /」,而1910_1567是現有代理的有效標識(我在創建過程中創建代理並使用其ID)。

我已經看到關於休息後獲得405的其他問題,但所有的解決方案都與網址有關,在我的情況下,網址是正確的。我甚至在測試之外運行設置,並通過瀏覽器訪問該URL以獲取對象和對象的確存在。但是當我嘗試發佈到它 - 405。

任何想法?

謝謝!

+0

PS我覺得它很顯而易見的,但是當我重寫update()函數並添加打印時,打印永遠不會被調用,例如,我得到的不是更新的實現,而是之前的版本。真的看起來像網址相關,但我驗證了網址和它的確定:/ –

+0

是否應該在後面的斜槓?如果你設置了'router = SimpleRouter(trailing_slash = False)'? – Railslide

+0

@Railslide發佈網址通常以斜線結尾,但我確實嘗試了您的建議並得到了相同的結果。 –

回答

1

POST應該是爲了創造目的。如果您想用ViewSet進行更新,您需要改爲PUT或PATCH(部分更新)。

編輯: 想了解更多,這裏的一對用於REST API的HTTP方法的一些解釋: http://restful-api-design.readthedocs.org/en/latest/methods.html

這是DRF文件在還描述: http://www.django-rest-framework.org/api-guide/routers/#simplerouter

+0

你確定嗎?你可以添加鏈接到文檔參考?謝謝:) –

+0

當然,這是在路由器部分描述:http://www.django-rest-framework.org/api-guide/routers/#simplerouter – Linovia

+0

確實,你是對的。我習慣於休息apis,接受「post」作爲更新現有對象的方式,我想django-rest對它更嚴格......謝謝! –

1

很可能你的網址在某種程度上與某些不同的url的正則表達式匹配,並且該請求被分派到一些不允許發佈請求的其他視圖。你可以在你的urls.py中提到其他urls嗎?事實上,您可以通過在視圖的分派方法中添加pdb(調試器)來驗證此情況。如果你把它交給了pdb,那麼你可以認爲我錯了。

如果情況並非如此,那麼您可以使用調試器從調度方法中評估問題。萬一您對如何做任何懷疑 -

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) 

發現的解決方案: -

你傳入ID的網址,所以這個請求將被路由到僅詳細信息視圖,詳細視圖由於資源已經存在,因此允許對資源執行GET,PUT和DELETE操作。因此要創建資源,請不要提供該ID。否則使用PUT請求併爲PUT中的創建提供支持。

+0

感謝hspandher,但這不是問題。命名空間「/ chat/rest」對於這個對象api是唯一的,並且只是爲了確保我將get()調用添加到上面一行中的同一個url,並且它能正常工作並返回代理對象。 (我寧願不發佈網址,因爲它的種類很長,我不想在這個問題上添加「噪音」) –

+0

感謝您的調試示例!我調試了調度,發現ViewSet對象沒有post方法!由於這一行,它返回405:handler = getattr(self,request.method.lower(),self.http_method_not_allowed),其中request.method確實是post。那麼爲什麼我沒有在我的ViewSet中發佈,如果我使用viewsets.ModelViewSet?任何想法是如何有意義的?謝謝! :) –

+0

它只發生在測試或瀏覽器? – hspandher