我們最終的視圖技巧利用了一個(gè)高級(jí)python技術(shù)。 假設(shè)你發(fā)現(xiàn)自己在各個(gè)不同視圖里重復(fù)了大量代碼,就像 這個(gè)例子:
def my_view1(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template1.html')def my_view2(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template2.html')def my_view3(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template3.html')這里,每一個(gè)視圖開始都檢查request.user是否是已經(jīng)認(rèn)證的,是的話,當(dāng)前用戶已經(jīng)成功登陸站點(diǎn)否則就重定向/accounts/login/ (注意,雖然我們還沒(méi)有講到request.user,但是14章將要講到它.就如你所想像的,request.user描述當(dāng)前用戶是登陸的還是匿名)
如果我們能夠叢每個(gè)視圖里移除那些 重復(fù)代,并且只在需要認(rèn)證的時(shí)候指明它們,那就完美了。 我們能夠通過(guò)使用一個(gè)視圖包裝達(dá)到目的。 花點(diǎn)時(shí)間來(lái)看看這個(gè):
def requires_login(view): def new_view(request, *args, **kwargs): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') return view(request, *args, **kwargs) return new_view函數(shù)requires_login,傳入一個(gè)視圖函數(shù)view,然后返回一個(gè)新的視圖函數(shù)new_view.這個(gè)新的視圖函數(shù)new_view在函數(shù)requires_login內(nèi)定義 處理request.user.is_authenticated()這個(gè)驗(yàn)證,從而決定是否執(zhí)行原來(lái)的view函數(shù)
現(xiàn)在,我們可以從views中去掉if not request.user.is_authenticated()驗(yàn)證.我們可以在URLconf中很容易的用requires_login來(lái)包裝實(shí)現(xiàn).
from django.conf.urls.defaults import *from mysite.views import requires_login, my_view1, my_view2, my_view3urlpatterns = patterns('', (r'^view1/$', requires_login(my_view1)), (r'^view2/$', requires_login(my_view2)), (r'^view3/$', requires_login(my_view3)),)優(yōu)化后的代碼和前面的功能一樣,但是減少了代碼冗余 現(xiàn)在我們建立了一個(gè)漂亮,通用的函數(shù)requires_login()來(lái)幫助我們修飾所有需要它來(lái)驗(yàn)證的視圖
包含其他URLconf
如果你試圖讓你的代碼用在多個(gè)基于Django的站點(diǎn)上,你應(yīng)該考慮將你的URLconf以包含的方式來(lái)處理。
在任何時(shí)候,你的URLconf都可以包含其他URLconf模塊。 對(duì)于根目錄是基于一系列URL的站點(diǎn)來(lái)說(shuō),這是必要的。 例如下面的,URLconf包含了其他URLConf:
from django.conf.urls.defaults import *urlpatterns = patterns('', (r'^weblog/', include('mysite.blog.urls')), (r'^photos/', include('mysite.photos.urls')), (r'^about/$', 'mysite.views.about'),)admin模塊有他自己的URLconf,你僅僅只需要在你自己的代碼中加入include就可以了.
這里有個(gè)很重要的地方: 例子中的指向 include() 的正則表達(dá)式并 不 包含一個(gè) $ (字符串結(jié)尾匹配符),但是包含了一個(gè)斜桿。 每當(dāng)Django遇到 include() 時(shí),它將截?cái)嗥ヅ涞腢RL,并把剩余的字符串發(fā)往包含的URLconf作進(jìn)一步處理。
繼續(xù)看這個(gè)例子,這里就是被包含的URLconf mysite.blog.urls :
from django.conf.urls.defaults import *urlpatterns = patterns('', (r'^(/d/d/d/d)/$', 'mysite.blog.views.year_detail'), (r'^(/d/d/d/d)/(/d/d)/$', 'mysite.blog.views.month_detail'),)通過(guò)這兩個(gè)URLconf,下面是一些處理請(qǐng)求的例子:
新聞熱點(diǎn)
疑難解答
圖片精選