django中的權限控制(form增刪改)


  Django默認提供了權限控制,但只能對使用了其自帶的登錄認證的用戶進行權限控制,說白了就是只能對存儲在auth_user表中的用戶進行權限控制,但不能對未登錄過的用戶進行權限控制。但如果通過集成LDAP認證后的用戶,其用戶也會被緩存到該表中,即變相實現了AD用戶也能進行權限控制。

  權限是auth 應用中定義的Permission類型;User與Permission是many-to-many的關系。

   Django對於每個模型類,自動增加add、change、delete三種權限,以便於權限控制。當然你也可以設定自己的權限。比如有一個名為hv的model,則該model就有了add、change和delete三種權限,可以在admin后台查看,如下圖所示:

  

  Django可以在view層面進行權限控制,即是否允許某個用戶訪問某個view,使用@permission_required修飾符實現。也可以通過request.user.has_perm() 來對add、change、delete三個動作分別進行權限控制。

  一、對某個view進行權限控制,使用@permission_required()修飾符:

  如果當前用戶沒有aptest.change_hv權限,則無法訪問add頁面,登錄后依然還會繼續跳回登錄頁面。

from django.contrib.auth.decorators import login_required,permission_required #導入權限控制模塊
@permission_required('aptest.change_hv',login_url="/aptest/loginauth") #第一個參數表示所需要的權限(權限名稱通過user.get_all_permissions()方法查看),第二個參數定義需要登錄到的url,默認為account/login。 def add(request):
    ......
    ......

  查看某個用戶當前權限列表:

from django.contrib.auth.models import User
user = User.objects.get(username=request.user.username)
print user.get_all_permissions() #查看當前用戶所具有的權限列表,返回值是permission name的list
#print user.get_group_permissions()方法列出用戶所屬group的權限

  返回如下,permission name list:

  

 

  二、對add、change、delete三個動作分別進行權限控制(比如用戶登錄一個頁面后,可以查看頁面內容,但不能進行增、刪、改動作):

  實例:用戶登錄后,判斷是否具有add權限,如果沒有則不能新增條目,實現如下:

  

  編輯view視圖,內容如下:

@login_required(login_url="/aptest/loginauth") #不需要再使用permission_required()裝飾器 def add(request):
    hvs = hv.objects.all()
    user = User.objects.get(username=request.user.username)
    print 'add page: ',user.get_all_permissions()if request.method == 'POST':
        form = hvform(request.POST)
        if form.is_valid(): #判斷輸入數據是否合法
            #print form.cleaned_data['name'],form.cleaned_data['ip']
            fc = form.cleaned_data
            if request.user.has_perm('aptest.add_hv'): #檢查用戶是否具有add權限,如果沒有則不能保存新增內容
                form.save()
            else:
                err.append(str(request.user.username) + 'doesnot has add permission.')
        else:
            err.append(form.errors) #輸出錯誤信息
    else:
        form = hvform()
    ls = range(10)
    context={'hour_offset':hour_offset,'ls':ls,'err':err,'hvs':hvs}
    return render(request,'aptest/form.html',context)

修改hv model中的一條記錄

from django.shortcuts import get_object_or_404
try
: item = get_object_or_404(hv,name=name) form=hvform(request.POST,instance=item) if form.is_valid(): #判斷輸入數據是否合法。如果先用form=hvform(request.POST)去檢查數據是否合法,此處由於name是主鍵,則會報錯,提示該name已存在。 if request.user.has_perm('aptest.change_hv'): #檢查用戶是否具有change權限,如果沒有則不能進行修改 form.save() else: err.append(str(request.user.username) + 'doesnot has change permission.') else: err.append(form.errors.values()[0][0]) #輸出錯誤信息,最好是自定義錯誤信息,此處輸出中文亂碼 except Exception: err...

刪除form中一條記錄,直接item.delete()即可。

 

 User和Group對象Permission管理:

user.user_permissions = [permission_list]
user.user_permissions.add(permission, permission, ...) #增加權限
user.user_permissions.remove(permission, permission, ...) #刪除權限
user.user_permissions.clear() #清空權限

group permission管理邏輯與user permission管理一致,group中使用permissions字段做權限管理:

group.permissions = [permission_list]
group.permissions.add(permission, permission, ...)
group.permissions.remove(permission, permission, ...)
group.permissions.clear()

檢查User或group權限用has_perm()方法:
user.has_perm('appname.add_modelname')
has_perm()方法的參數,即permission的codename,但傳遞參數時需要加上model 所屬app的前綴,格式為<app label>.<permission codename>。

user.get_all_permissions()方法列出用戶的所有權限,返回值是permission name的list
user.get_group_permissions()方法列出用戶所屬group的權限,返回值是permission name的list

 

檢查用戶所屬組:
dir(request.user.groups)

request.user.groups.values() #返回用戶所屬組
[x['name'] for x in request.user.groups.values()] #返回用戶所屬組

 

 

示例:給當前用戶添加hv model的change權限

可以在django_content_type和auth_permission表中查看ContentType、permission中的content_type、codename名稱

from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

#給當前用戶添加hv model的change權限
    user = User.objects.get(username=request.user.username)
    content_type = ContentType.objects.get_for_model(hv)
    permission = Permission.objects.get(content_type=content_type, codename='change_hv')
    request.user.user_permissions.add(permission)
 #request.user.user_permissions.remove(permission) #刪除當前用戶緩存的權限
    if hasattr(user, '_perm_cache'):
        delattr(user, '_perm_cache')
    print ,request.user,user.get_all_permissions()

 

#################################################################################

   Django-guardian基於django的原生邏輯擴展了django的權限機制,應用django-guardian后,可使用django-guardian提供的方法以及django的原生方法檢查全局權限,django-guardian提供的object permission機制使django的權限機制更完善。具體參考:http://www.jianshu.com/p/01126437e8a4
 

 還可以通過如下方法限制用戶是否可以訪問view(http://www.jb51.net/article/69893.htm):

例如,下面視圖確認用戶登錄並是否有 polls.can_vote權限:

?
1
2
3
4
5
def vote(request):
  if request.user.is_authenticated() and request.user.has_perm( 'polls.can_vote' )):
   # vote here
  else :
   return HttpResponse( "You can't vote in this poll." )

並且Django有一個稱為 user_passes_test 的簡潔方式。它接受參數然后為你指定的情況生成裝飾器。

?
1
2
3
4
5
6
7
def user_can_vote(user):
  return user.is_authenticated() and user.has_perm( "polls.can_vote" )
 
@user_passes_test (user_can_vote, login_url = "/login/" )
def vote(request):
  # Code here can assume a logged-in user with the correct permission.
  ...

user_passes_test 使用一個必需的參數: 一個可調用的方法,當存在 User 對象並當此用戶允許查看該頁面時返回 True 。 注意 user_passes_test 不會自動檢查 User是否認證,你應該自己做這件事。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM