2016-03-24 69 views
1

Django的解耦許可式檢查:從調用查看

我想脫鉤允許在Django檢查解耦權限檢查。Django的:從調用查看

當前回退:如果您使用像login_required這樣的裝飾器,那麼您無法事先知道用戶是否有權這樣做。

我想這分爲兩個步驟:

  1. 檢查權限
  2. 調用視圖。

使用案例1:管理工具

我要爲管理員,他們可以檢查用戶的訪問權限的工具。這要求:

  1. 該檢查不能使用當前的request.user,因爲這是錯誤的用戶對象。
  2. 檢查不能實際調用視圖,因爲這可能會改變數據。

用例2:顯示鏈接已禁用。

如果用戶沒有查看鏈接頁面的權限,我想將鏈接顯示爲已禁用(灰色並且沒有「href」)。

回到了「OK」和一個布爾拒絕「權限」是很好的。但是,如果管理員可以得到原因,那麼最大的好處是。

例子:

  1. 管理員打開 「檢查燙髮工具」
  2. 他選擇了一個視圖/ URL
  3. 管理員點擊 「提交」

結果:

------------------------------ 
| User  | Allowed | Reason 
------------------------------ 
| fooadmin | Yes | is_superuser 
| foouser | No  | missing permission "view-bar-at-midnight" 
| foobar | Yes | User has permission "view-bar-at-midnight" 

問題

如何讓這個夢想成真?

...只是爲了記錄,我張貼的想法Django的開發列表:https://groups.google.com/forum/#!topic/django-developers/rpTh4G3BgIQ

+2

它不清楚你問什麼,如果用戶沒有登錄,然後他們沒有權限 – Sayse

+0

@Sayse從我個人理解,guettli希望一個「查看X網站」功能(其中X是任何用戶)。 –

+0

因此,我不確定您希望在** Use Case 1 **中使用權限檢查。如果您對Django Admin界面的'http:// domain/admin'很滿意,那麼可以通過在您的用戶模型中添加一個布爾變量(或者如果您擁有更多種類的權限)來解決權限問題,您可以在管理界面的表格中使用[模型管理對象](https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#modeladmin-objects)在'admin.py'中。 –

回答

3

我假設你已經有了查看每個視圖/ URL所需的所有權限的列表?即您知道URL /bar需要權限superuserview-bar-at-night提前?

如果是這樣,嘗試添加一個ViewPermissions模型models.py第一:在admin.py

from django.db import models 

class ViewPermissions(models.Model): 
    view_url = models.CharField(help_text="The URL of this view") 

然後:

from models import ViewPermissions 
from django.contrib.admin.widgets import FilteredSelectMultiple 
from django.contrib.auth.models import Permission 
from django.contrib import admin 
from django import forms 

class ViewPermissionFormField(forms.ModelForm): 
    permissions = forms.ModelMultipleChoiceField(
     widget=FilteredSelectMultiple("Permissions", is_stacked=False), 
     queryset=models.Permission.objects.all() 
    ) 

    def save(self, commit=True): 
     extra_field = self.cleaned_data.get('extra_field', None) 
    return super(ViewPermissionFormField, self).save(commit=commit) 

    class Meta: 
     fields = '__all__' 
     model = ViewPermissions 

class ViewPermissionsAdmin(admin.ModelAdmin): 
    form = ViewPermissionsFormField 
    fieldsets = (
     (None, { 
      'fields': 'view_url', 'permissions' 
     }) 
    ) 

現在你可以在管理員權限添加到每個視圖URL跟蹤的東西。 FYI你可以create your own custom permissions並將它們添加到Django的現有的。

您可以創建一個管理員表單,用於提取用戶,列出他們的權限,然後利用ViewPermissions查看用戶可以根據訪問權限(用例1)訪問哪些網址。

現在,您可以檢查用戶的許可,您的視圖函數(或類,如果這就是你如何定義你的看法),像這樣:

from django.contrib.auth.models import Permission 
from models import ViewPermissions 

def my_view(request) 
    view_url = request.get_current_url() 
    permissions_required = ViewPermissions.objects.filter(view_url = view_url).permissions 
    context['user_permissions'] = [] 
    for p in permissions_required: 
     if request.user.has_permission(p): 
      context['user_permissions'].append(p) 

現在,你可以把這些權限到您的模板和變灰鏈接相應(用例2)。

所以類似的東西可能工作...

+0

我喜歡這個解決方案。將權限存儲在DB模型中....很好。 – guettli