2011-08-16 79 views
1

基於類的視圖的Django的as_view()語法一直困擾着我。基本上,我厭倦了爲每個基於類的視圖執行my_view = MyView.as_view(),或者將as_view()放在每個url的每一行中,我使用基於c的視圖。我認爲一個類裝飾器將是一個更清晰的方法來實現這一點,我想弄清楚如何實現這一點,爲我自己的代碼,並分享django片段,以防其他人感興趣。所以我的問題是:有沒有一種合理的方式來實現「as_view」裝飾器,以便下面的代碼可以正常工作?as_view()(用於基於類的視圖)是否可以在裝飾器中實現?

@as_view(my_view) 
class MyView(View): 
    pass 

這將基本上等同於:

class MyView(View): 
    pass 
my_view = MyView.as_view() 

感謝,這也幫助我學習Python的高級功能(即裝飾)。

,想到奔

+1

整個'as_view'事情是爲了讓它很明顯,類將被實例化每個請求一次,所以你不會試圖存儲它們的狀態。所以任何解決方案都需要保持這個。 –

回答

1

一種方法是有類裝飾只是setattr一些對象,它將包含所有as_views你想要定義。然後,您可以使用您的urls.py

import re 

class Views(object): 
    """Empty object for holding as_view method""" 
views = Views() 

def convert_name(name): 
    """convert CapWords into cap_words""" 
    return name[0].lower() + re.sub(r'([A-Z])', lambda m:"_" + m.group(0).lower(), name[1:]) 

def as_view(views): 
    """Adds decorated class-based views' as_view methods to views container""" 
    def decorator(cls): 
     name = convert_name(cls.__name__) 
     setattr(views, name, cls.as_view) 
     return cls 
    return decorator 

,然後在views.py你會使用這樣的:

from as_view_decorator import views, as_view 

@as_view(views) 
class MyView(View): 
    .... 

..和MyView.as_view將被存儲在views對象上views.my_view

你也可以做你的views.py是這樣的:

from as_view_decorator impor as_view 
import sys; mod = sys.modules[__name__] 

@as_view(mod) 
class MyView(View): 
    ... 

這將設置my_view爲您views模塊上的屬性。然後,您可以在您的urls.py

from app.views import my_view 

urlpatterns = patterns('',  
    url(r'^$', my_view()), 
) 

我覺得做my_view = MyView.as_view是非常簡單和可讀性,所以我坦率地喜歡我自己。

+0

有趣的實現。玩過它。最後我決定同意你的最後一行:) –

相關問題