2016-11-21 50 views
0

我第一次使用Django(我也是一般的Python新手),我一直在努力解決與基於類的視圖有關的某個問題。我來自Laravel的PHP,在那裏你可以有所謂的「RESTful資源控制器」。在Django中的資源視圖

對於每個不熟悉Laravel的人來說:這個想法是每個'資源'有一個控制器(或者用Django說話)。該控制器/視圖定義的方法,如index()show()create()store()edit()等,爲這些控制器方法的相關聯的URL和HTTP方法GET /photosGET /photos/1GET /photos/createPOST /photosGET /photos/1/edit分別(例如,如果你正在處理與照片)。在Laravel的路由中,您必須聲明一行Route::resource('photos', 'PhotoController'),這些URL將自動生成。欲瞭解更多信息,我參考Laravel's docs

我真的很喜歡這種模式,我想在Django中使用它。

據我所知,Django並沒有真正具備這種開箱即用的功能。 Django確實具有基於類的視圖,但這些視圖不代表資源。相反,您可以查看您的'index()'(PhotoListView),查看您的'show()'(PhotoDetailView)等等。

我不知道我應該如何在Django中實現這個模式,我甚至不確定我想要的是不是一個好主意。

研究後,我發現了一些信息,可能是有用的:

http://watchitlater.com/blog/2010/02/django-restful-resources/
https://baxeico.wordpress.com/2014/06/25/put-and-delete-http-requests-with-django-and-jquery/

我不知道從第一鏈接自定義視圖類實現了這個股票的Django視圖可以」 t(一個普通的Django View或多或少都是相同的東西,對吧?),我不認爲第二個鏈接完全符合我的要求(如果我理解正確,文章僅僅將中間件描述爲問題的解決方案Django不會將請求中的DELETE/PUT請求發送的數據放入請求中)。

在此基礎上,我設計了兩種解決辦法:

  • 使用一個單一的線相匹配的所有URL一定的資源,像這樣的URL配置:

    url(r'^photos/(.*)$', PhotoView.as_view())

    as_view()然後,自定義View基類的函數將處理諸如/photos,/photos/1/photos/1/edit等URL的路由到正確的類方法。缺點是你把路由放到一個視圖中(而不是正確的位置),並且你不能使用命名模式來引用代碼中其他地方的URL。儘管它最接近它在Laravel的作品。

  • 使用單獨的行URL配置每個網址,如:

    url(r'^photos$', PhotoView.index) url(r'^photos/(\d+)$', PhotoView.show) url(r'^photos/(\d+)/edit$', PhotoView.edit)

    這樣做的好處是,命名模式照常上班,和所有的路由停留在URL配置。但是,我不知道如何在View類的實現方面做到這一點(我必須修飾每個方法@classonly方法,正確)。

對不起,我很樂意聽到你的想法如何最好地解決這個問題。或者,也許我只是瘋狂的batshit,我應該像每個正常的Django編碼器一樣使用基於函數的視圖嗎?

+1

你見過[Django的REST框架(http://www.django-rest-framework.org/)? –

+0

@JensAstrup是的,我(一再)偶然發現了這一點。我不是建立一個API,但一個網站/ webapp。 – Compizfox

回答

0

我最終編寫了一個自定義的基於類的視圖,這個視圖或多或少的混合了這個問題中提出的兩個解決方案。

總體思路是我有一個ResourceView,它跟Django的View類(它有as_view()dispatch()方法)具有相同的結構。就像Django的View一樣,as_view()定義了一個返回到URLconf的閉包。該關閉依靠dispatch()將請求分發到正確的(子)方法。爲此,它使用'2d映射'(dict字典)來確定應該爲路由(URL)和HTTP方法的哪個組合調用哪個方法。與Django的View不同的是,在URLconf中調用as_view()時使用了一個指定路由的參數。

我也有一個ResourceRouter自動生成對應於該視圖的URLconf。這種方法受到DRF如何處理這個問題的啓發。

最後但並非最不重要我寫了一個將模型實例「綁定」到該方法的裝飾器,因此模型實例被傳遞給view方法,而不是pk。

的代碼可以在這裏找到:https://gist.github.com/Compizfox/c4e3044755417f59dc33ce97ac8ca07c

1

正如Jens在評論中建議的那樣。第三方Django Rest Framework是我們對你所描述的laravel控制器最接近的東西。具體要看的項目是viewsets

Django REST框架允許您將一組相關視圖的邏輯組合在一個名爲ViewSet的類中。在其他框架 中,您也可能會發現概念上類似的實現,名稱爲 ,如'Resources'或'Controllers'。

DRF的學習曲線非常陡峭。 DRF還傳達了它僅適用於創建API的印象。但是,現實情況是DRF可以用於render HTML and process ordinary HTML forms

REST框架適用於返回兩種API風格的響應,以及 常規HTML頁面。此外,序列化器可以用作HTML表格 並在模板中呈現。

當然的選擇是使用基於類的視圖。缺點是它不能在單個類中提供DRF視圖集的所有功能。但一切都不會丟失。您可以使用CBV Mixins來混合和匹配您所需的功能。

+0

謝謝。我的確有一種印象,那就是隻用於API,而不是用於網站,這就是爲什麼我沒有更多地關注它。 DRF似乎是我正在尋找的,但是我已經寫了一個自定義的View基類,它可以做我想做的事情,並且比DRF簡單得多(雖然不是很靈活),並且不需要學習全新的框架。完成後我會將其作爲答案發布。 – Compizfox

+0

聽起來像是一個計劃,但是你不需要從頭開始編寫一個視圖類,你可以像前面提到的那樣混合和匹配mixins,這樣你將不得不編寫很少的代碼 – e4c5

+0

太遲了,我已經寫了它...;)我會檢查是否可以使用這些mixins重構它。謝謝你的提示。 – Compizfox