我們最終的視圖技巧利用了一個高級python技術。 假設你發現自己在各個不同視圖里重復了大量代碼,就像 這個例子:
- 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')
這里,每一個視圖開始都檢查request.user是否是已經認證的,是的話,當前用戶已經成功登陸站點否則就重定向/accounts/login/ (注意,雖然我們還沒有講到request.user,但是14章將要講到它.就如你所想像的,request.user描述當前用戶是登陸的還是匿名)
如果我們能夠叢每個視圖里移除那些 重復代,并且只在需要認證的時候指明它們,那就完美了。 我們能夠通過使用一個視圖包裝達到目的。 花點時間來看看這個:
- 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
函數requires_login,傳入一個視圖函數view,然后返回一個新的視圖函數new_view.這個新的視圖函數new_view在函數requires_login內定義 處理request.user.is_authenticated()這個驗證,從而決定是否執行原來的view函數
現在,我們可以從views中去掉if not request.user.is_authenticated()驗證.我們可以在URLconf中很容易的用requires_login來包裝實現.
- from django.conf.urls.defaults import *
- from mysite.views import requires_login, my_view1, my_view2, my_view3
- urlpatterns = patterns('',
- (r'^view1/$', requires_login(my_view1)),
- (r'^view2/$', requires_login(my_view2)),
- (r'^view3/$', requires_login(my_view3)),
- )
優化后的代碼和前面的功能一樣,但是減少了代碼冗余 現在我們建立了一個漂亮,通用的函數requires_login()來幫助我們修飾所有需要它來驗證的視圖
包含其他URLconf
如果你試圖讓你的代碼用在多個基于Django的站點上,你應該考慮將你的URLconf以包含的方式來處理。
在任何時候,你的URLconf都可以包含其他URLconf模塊。 對于根目錄是基于一系列URL的站點來說,這是必要的。 例如下面的,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就可以了.
這里有個很重要的地方: 例子中的指向 include() 的正則表達式并 不 包含一個 $ (字符串結尾匹配符),但是包含了一個斜桿。 每當Django遇到 include() 時,它將截斷匹配的URL,并把剩余的字符串發往包含的URLconf作進一步處理。
繼續看這個例子,這里就是被包含的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'),
- )
通過這兩個URLconf,下面是一些處理請求的例子:
新聞熱點
疑難解答