Django視圖指向一個函數,如果您只想更改某些功能,則這可能是一個問題。是的,我可以有百萬個關鍵字參數,如果函數中有更多的語句,但我更多地考慮面向對象的方法。Django中的類視圖
例如,我有一個顯示用戶的頁面。該頁面與顯示組的頁面非常相似,但與僅使用其他數據模型不太相似。組也有成員等...
一種方法是指向視圖的類方法,然後擴展該類。有沒有人嘗試過這種方法或有任何其他想法?
Django視圖指向一個函數,如果您只想更改某些功能,則這可能是一個問題。是的,我可以有百萬個關鍵字參數,如果函數中有更多的語句,但我更多地考慮面向對象的方法。Django中的類視圖
例如,我有一個顯示用戶的頁面。該頁面與顯示組的頁面非常相似,但與僅使用其他數據模型不太相似。組也有成員等...
一種方法是指向視圖的類方法,然後擴展該類。有沒有人嘗試過這種方法或有任何其他想法?
我創建並使用了我自己的通用視圖類,定義了__call__
,因此該類的一個實例是可調用的。我很喜歡;雖然Django的泛型視圖允許通過關鍵字參數進行一些定製,但是OO泛型視圖(如果它們的行爲被拆分成多個單獨的方法)可以通過子類化進行更細粒度的自定義,這使我可以更少地重複自己。 (我厭倦了隨時重寫相同的創建/更新視圖邏輯,因爲我需要調整Django的通用視圖不允許的東西)。
我已經在djangosnippets.org上發佈了一些代碼。
我看到的唯一真正的缺點是內部方法調用的泛濫,這可能會影響性能。我認爲這不是一個大問題; Python代碼執行很少會成爲Web應用程序中的性能瓶頸。
UPDATE:Django自己的generic views現在是基於類的。
UPDATE:FWIW,自從寫了這個答案以來,我改變了對基於類的觀點的看法。在一些項目中廣泛使用它們之後,我覺得它們傾向於編寫令人滿意的DRY代碼,但以後很難閱讀和維護,因爲功能遍佈於許多不同的地方,並且子類是如此依賴的關於超類和mixin的每個實現細節。我現在覺得TemplateResponse和查看裝飾器是分解視圖代碼的更好的答案。
聽起來像你想要結合不應該組合的東西。如果您需要在視圖中執行不同的處理,具體取決於它是否是您想要查看的用戶或組對象,那麼您應該使用兩種不同的視圖函數。
另一方面,可以有你想從對象中提取出來的常見習語_詳細類型視圖......也許你可以使用裝飾器或只是輔助函數?
-Dan
如果你只是從模型顯示數據,爲什麼不使用Django Generic Views?它們旨在讓您輕鬆展示模型中的數據,而無需編寫自己的視圖和將URL參數映射到視圖,獲取數據,處理邊緣情況,呈現輸出等內容。
除非您想做一些有點複雜的東西,使用通用視圖是要走的路。它們比它們的名字所暗示的功能強大得多,如果你只是顯示模型數據,通用視圖將完成這項工作。
如果您想在頁面之間共享通用功能,我建議您查看自定義標籤。他們相當於easy to create,而且非常強大。
另外,templates can extend from other templates。這使您可以擁有一個基本模板來設置頁面的佈局,並在填充空白的其他模板之間共享該模板。您可以將模板嵌套到任何深度;允許您在單獨的一組相關頁面上指定佈局。
我不認爲在模板中放置太多的邏輯是一個好主意。 – 2010-09-17 11:48:39
你總是可以創建一個類,覆蓋__call__
功能,然後將URL文件指向類的一個實例。您可以查看FormWizard課程,瞭解如何完成這項工作。
標記處理器吃了你的\ _ \ _'s。使用\\ _隱藏標記。類\ _ \ _ call \ _ \ _方法就是所謂的。問題是要確保urls.py具有可用的類的實例。 它使你的urls.py稍微複雜一些。 – 2008-09-17 02:07:54
通用視圖通常是要走的路,但最終你可以自由地處理URL但不管你想要的。 FormWizard以基於類的方式執行某些操作,就像使用RESTful API的某些應用程序一樣。
基本上用一個URL給你一堆變量,並提供一個可調用的地方,你提供的調用完全取決於你 - 標準的方法是提供一個函數 - 但是最終Django對你的內容沒有限制做。
我的確同意,如何做到這一點的更多的例子會很好,FormWizard可能是開始的地方。
我需要使用基於類的視圖,但我希望能夠在我的URLconf中使用該類的全名,而不必在使用它之前實例化視圖類。什麼幫助我是一個令人驚訝的簡單元類:
class CallableViewClass(type):
def __call__(cls, *args, **kwargs):
if args and isinstance(args[0], HttpRequest):
instance = super(CallableViewClass, cls).__call__()
return instance.__call__(*args, **kwargs)
else:
instance = super(CallableViewClass, cls).__call__(*args, **kwargs)
return instance
class View(object):
__metaclass__ = CallableViewClass
def __call__(self, request, *args, **kwargs):
if hasattr(self, request.method):
handler = getattr(self, request.method)
if hasattr(handler, '__call__'):
return handler(request, *args, **kwargs)
return HttpResponseBadRequest('Method Not Allowed', status=405)
我現在既可以實例化視圖類和使用情況的視圖功能,或者我可以簡單地指向我的URL配置上我的課,並有元類實例化(和調用)對我來說是視圖類。這可以通過檢查__call__
的第一個參數來工作 - 如果它是HttpRequest
,它必須是一個實際的HTTP請求,因爲使用HttpRequest
實例嘗試實例化一個視圖類是無稽之談。
class MyView(View):
def __init__(self, arg=None):
self.arg = arg
def GET(request):
return HttpResponse(self.arg or 'no args provided')
@login_required
class MyOtherView(View):
def POST(request):
pass
# And all the following work as expected.
urlpatterns = patterns(''
url(r'^myview1$', 'myapp.views.MyView', name='myview1'),
url(r'^myview2$', myapp.views.MyView, name='myview2'),
url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'),
url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'),
)
完全真棒 – Anentropic 2010-10-27 19:05:39
您可以使用Django的通用視圖。你可以很容易地實現所需的功能徹底的Django通用視圖
Python執行不是瓶頸,但可能會影響網站的可擴展性和整體性能。我很高興memcache存在! – StefanNch 2012-12-23 12:06:46