2017-05-23 37 views
2

我正在使用名爲django-dashing的django庫,它具有一組預定義的呈現儀表板的url。我將它們導入這樣Django爲Blackboxed路由URL編寫身份驗證重定向

urlpatterns = [ 
    ... 
    url(r'^dashboard/', include(dashing_router.urls)), 
    ... 
] 

我希望路由器只能由管理員,我可以與內django-dashing一些配置設置做訪問。但是,當非管理員用戶嘗試訪問/dashboard/時,我想將它們重定向到django的/admin/面板以讓它們登錄,而不是拋出403django-dashing

由於django-dashing意見有效blackboxed,我想知道是否有寫「前視圖」,將攔截請求/dashboard/,運行一些代碼的方式 - 特別是,做適當的重定向 - 然後繼續到實際的儀表板上。

我知道這將是很容易做到通過寫兩個URL,如/dashboard-auth/其重定向到/dashboard/,但我不希望用戶必須到一個URL去另一個

任何建議?

回答

0

如果您願意look inside這個「黑匣子」的勇猛網址,您可以看到/dashboard/Dashboard視圖處理。你可以繼承這個視圖,並捕獲PermissionDenied錯誤。

from django.core.exceptions import PermissionDenied 

from dashing.views import Dashboard 

class MyDashboard(Dashboard): 
    def get(self, request, *args, **kwargs): 
     try: 
      return super(MyDashboard, self).get(request, *args, **kwargs) 
     except PermissionDenied: 
      return redirect('/admin/') 

添加您的看法以上瀟灑網址:

urlpatterns = [ 
    ... 
    url(r'^dashboard/$', MyDashboard.as_view()) 
    url(r'^dashboard/', include(dashing_router.urls)), 
    ... 
] 
+2

其他儀表板網址呢?他們將對任何人開放 – Brobin

+0

@Brobin你認爲他們會對任何人開放嗎?我沒有從其他網址中刪除任何權限檢查,他們將擁有與之前相同的權限檢查。 – Alasdair

+1

他們不會對任何人開放,他們會接受誰在'django-dashing'的配置權限配置 – mjkaufer

1

我會做它是由overridding瀟灑的默認路由器的方式。所有的url都是由Router類動態生成的,所以通過覆蓋get_urls方法,可以將每個函數包裝在staff_member_required裝飾器中。

from django.contrib.admin.views.decorators import staff_member_required 
from django.conf.urls import url 

from dashing.utils import Router 
from dashing.views import Dashboard 


class AdminRequiredRouter(Router): 

    def get_urls(self): 
     urlpatterns = [ 
      url(r'^$', staff_member_required(Dashboard.as_view()), name='dashboard'), 
     ] 
     for widget, basename, parameters in self.registry: 
      urlpatterns += [ 
       url(r'/'.join((
        r'^widgets/{}'.format(basename), 
        r'/'.join((r'(?P<{}>{})'.format(parameter, regex) 
           for parameter, regex in parameters.items())), 
       )), 
        staff_member_required(widget.as_view()), 
        name='widget_{}'.format(basename)), 
      ] 
     return urlpatterns 

router = AdminRequiredRouter() 

然後包括你的路由器,而不是瀟灑的

from .router import router 

urlpatterns = [ 
    ... 
    url(r'^dashboard/', include(router.urls)), 
    ... 
] 
3

一個Django簡單的自定義中間件的是另一種選擇......

from django.core.urlresolvers import reverse 
from django.http import HttpResponseRedirect 

class DashingRedirectMiddleware(object): 

    def process_request(self, request): 
     if request.path.startswith('/dashing/') and not request.user.is_staff: 
      return HttpResponseRedirect(reverse('admin:login')) 
     return 

不要忘了這個中間件添加到你的Django定位...

MIDDLEWARE_CLASSES = [ 
    ... 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'yourapp.middleware.DashingRedirectMiddleware', 
    ... 
] 

或類似的東西。

+0

謝謝,絕對是最乾淨/最簡單的答案 – mjkaufer

+1

你也可以設置'next'參數:''{0}?next = {1}'。format(reverse ('admin:login'),request.path)',這樣用戶就可以登錄到他們登錄後試圖訪問的頁面。 – Brobin

+0

這個答案的唯一缺點是中間件會運行在對任何部分網站,這似乎有點矯枉過正 – mjkaufer