對(duì)Django中的權(quán)限和分組管理實(shí)例講解
權(quán)限
Django中內(nèi)置了權(quán)限的功能。他的權(quán)限都是針對(duì)表或者說(shuō)是模型級(jí)別的。比如對(duì)某個(gè)模型上的數(shù)據(jù)是否可以進(jìn)行增刪改查操作。他不能針對(duì)數(shù)據(jù)級(jí)別的,比如對(duì)某個(gè)表中的某條數(shù)據(jù)能否進(jìn)行增刪改查操作(如果要實(shí)現(xiàn)數(shù)據(jù)級(jí)別的,考慮使用django-guardian)。創(chuàng)建完一個(gè)模型后,針對(duì)這個(gè)模型默認(rèn)就有四種權(quán)限,分別是增/刪/改/查??梢栽趫?zhí)行完migrate命令后,查看數(shù)據(jù)庫(kù)中的auth_permission表中的所有權(quán)限。
字段:
content_type_id:是一個(gè)外鍵,參考表是django_content_type這個(gè)表,django就是根據(jù)這個(gè)來(lái)找到某一個(gè)具體的模型的。
codename: 表示權(quán)限的名字。
name: 對(duì)該權(quán)限的描述。
添加權(quán)限
通過(guò)定義模型添加權(quán)限:
如果我們想要增加新的權(quán)限,比如查看某個(gè)模型的權(quán)限,那么我們可以在定義模型的時(shí)候在Meta中定義好。
class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() author = models.CharField(max_length=20) class Meta: permissions = [ ('black_article','拉黑文章的權(quán)限'), ]
然后執(zhí)行makemigrations和migrate命令,就添加好了這一條權(quán)限。我們可以數(shù)據(jù)庫(kù)中的auth_permission表中看到我們添加的這一條權(quán)限。
通過(guò)代碼來(lái)添加權(quán)限。
權(quán)限都是django.contrib.auth.Permission的實(shí)例。這個(gè)模型包含三個(gè)字段,name、codename以及content_type,其中的content_type表示這個(gè)permission是屬于哪個(gè)app下的哪個(gè)models。
定義一個(gè)視圖函數(shù),然后寫入代碼:
from django.http import HttpResponse from .models import Article from django.contrib.auth.models import Permission,ContentType # Create your views here. def add_permission(request): content_type = ContentType.objects.get_for_model(Article) permission = Permission.objects.create(codename='white_article',name='將文章加入白名單',content_type=content_type) return HttpResponse('權(quán)限創(chuàng)建成功')
然后執(zhí)行這個(gè)視圖函數(shù),就能夠添加這個(gè)權(quán)限了。
注意: name字段是不能有重復(fù)的,否則會(huì)報(bào)錯(cuò)。
用戶與權(quán)限管理:
權(quán)限本身只是一個(gè)數(shù)據(jù),必須和用戶進(jìn)行綁定,才能起到作用。User模型和權(quán)限之間的管理,可以通過(guò)以下幾種方式來(lái)管理:
1、myuser.user_permissions.set(permission_list):直接給定一個(gè)權(quán)限的列表。
2、myuser.user_permissions.add(permission,permission,…):一個(gè)個(gè)添加權(quán)限。這里就不能傳入一個(gè)列表了,只能一個(gè)一個(gè)的傳入數(shù)據(jù)了。
3、myuser.user_permissions.remove(permission,permission,…):一個(gè)個(gè)刪除權(quán)限。
4、myuser.user_permissions.clear():清除所有的權(quán)限。
5、myuser.has_perm('<app_name>.'):判斷是否擁有某個(gè)權(quán)限。權(quán)限參數(shù)是一個(gè)字符串,格式是app_name.codename。
6、myuser.get_all_permissons():獲取所有的權(quán)限。
注意:
這個(gè)地方的User模型并不是我們自定義的User模型,而是Django內(nèi)置的一個(gè)User模型,而我們自定義的模型是不能夠這樣進(jìn)行操作的。django內(nèi)置的User模型我們需要導(dǎo)入:from django.contrib.auth.models import User。
現(xiàn)在,我們給User模型綁定Article模型的一些權(quán)限:
執(zhí)行上面的add方法和remove方法后需要執(zhí)行一下save()方法,否則將不能保存到數(shù)據(jù)庫(kù)中去。
views中新建一個(gè)視圖:
首先我們需要?jiǎng)?chuàng)建一個(gè)User用戶:
from django.contrib.auth.models import Permission,ContentType,User def createUser(request): user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111') return HttpResponse('用戶創(chuàng)建成功')
然后對(duì)該用戶的權(quán)限進(jìn)行操作:
from django.http import HttpResponse from .models import Article from django.contrib.auth.models import Permission,ContentType,User def operate_permission(request): user = User.objects.first() content_type = ContentType.objects.get_for_model(Article) permissions = Permission.objects.filter(content_type=content_type) for permission in permissions: print(permission) # 添加權(quán)限 user.user_permissions.set(permissions) # 清除所有的權(quán)限 # user.user_permissions.clear() # 查看是否擁有某個(gè)權(quán)限 if user.has_perm('authority.view_article'): print('這個(gè)用戶擁有view_article的權(quán)限') else: print('這個(gè)用戶沒(méi)有view_article的權(quán)限') return HttpResponse('操作權(quán)限的視圖')
權(quán)限限定裝飾器:
我們可以判斷某一個(gè)用戶是否擁有某個(gè)權(quán)限,再對(duì)它判斷是否可以訪問(wèn)某一個(gè)頁(yè)面。
要判斷某個(gè)用戶是否擁有某個(gè)權(quán)限,我們首先得登錄:
from django.contrib.auth import authenticate,login def my_login(request): username = 'xujin' password = '111111' # username和password輸入正確后這里會(huì)返回一個(gè)User對(duì)象 user = authenticate(request,username=username,password=password) # 判斷是否有該用戶 if user: # 使用django內(nèi)置的一個(gè)登錄函數(shù)來(lái)登錄,登錄成功之后會(huì)設(shè)置一個(gè)session值 login(request,user) else: return HttpResponse('用戶名或密碼錯(cuò)誤')
然后我們?cè)賹懭胩砑游恼碌暮瘮?shù)視圖:
def add_article(request): # 判斷用戶是否登錄了,這里的用戶是指后臺(tái)管理員的用戶,也就是Django的User模型中的用戶 # 而不是瀏覽網(wǎng)站的用戶 # 通過(guò)這個(gè)request.user.is_authenticated可以判斷是否登錄了 if request.user.is_authenticated: print('已經(jīng)登錄了') # 再判斷是否擁有這個(gè)權(quán)限 if request.user.has_perm('authority.add_article'): return HttpResponse('添加文章的頁(yè)面') else: # 403表示沒(méi)有權(quán)限的意思 return HttpResponse('你沒(méi)有訪問(wèn)該頁(yè)面的權(quán)限',status=403) else: return HttpResponse('你還沒(méi)有登錄,請(qǐng)登錄!??!')
這樣,我們就實(shí)現(xiàn)了對(duì)某個(gè)用戶的權(quán)限限制了。
上面這種方法是我們自己手動(dòng)實(shí)現(xiàn)的,Django也內(nèi)置一個(gè)裝飾器permission_required,來(lái)幫我們實(shí)現(xiàn)了這個(gè)功能:
from django.contrib.auth.decorators import permission_required # login_url沒(méi)有登錄跳轉(zhuǎn)至的頁(yè)面 # raise_exception=True,當(dāng)你沒(méi)有權(quán)限訪問(wèn)這個(gè)頁(yè)面的時(shí)候,就會(huì)拋出一個(gè)403錯(cuò)誤 # 如果我們?cè)诰W(wǎng)站中寫了403那個(gè)頁(yè)面的話,就會(huì)重定向到403哪一個(gè)頁(yè)面 @permission_required('front.add_article',login_url='front/login',raise_exception=True) def add_article(request): # 判斷用戶是否登錄了,這里的用戶是指后臺(tái)管理員的用戶,也就是Django的User模型中的用戶 # 而不是瀏覽網(wǎng)站的用戶 # if request.user.is_authenticated: # print('已經(jīng)登錄了') # if request.user.has_perm('authority.add_article'): # return HttpResponse('添加文章的頁(yè)面') # else: # # 403表示沒(méi)有權(quán)限的意思 # return HttpResponse('你沒(méi)有訪問(wèn)該頁(yè)面的權(quán)限',status=403) # else: # return HttpResponse('你還沒(méi)有登錄,請(qǐng)登錄?。?!') return HttpResponse('添加文章的頁(yè)面')
這樣,我們就不用寫上面那么多代碼了,只需要寫入我們的主體函數(shù)就可以了。
注意: 如果一個(gè)函數(shù)視圖需要多個(gè)權(quán)限才能進(jìn)入的話,我們可以將需要的權(quán)限放入一個(gè)列表中,然后再將這個(gè)列表放在裝飾器中。這個(gè)時(shí)候如果我們手動(dòng)實(shí)現(xiàn)這個(gè)裝飾器的功能的話,就要使用has_perms方法來(lái)判斷了。
分組:
權(quán)限有很多,一個(gè)模型就有最少四個(gè)權(quán)限,如果一些用戶擁有相同的權(quán)限,那么每次都要重復(fù)添加。這時(shí)候分組就可以幫我們解決這種問(wèn)題了,我們可以把一些權(quán)限歸類,然后添加到某個(gè)分組中,之后再把和把需要賦予這些權(quán)限的用戶添加到這個(gè)分組中,就比較好管理了。分組我們使用的是django.contrib.auth.models.Group模型, 每個(gè)用戶組擁有id和name兩個(gè)字段,該模型在數(shù)據(jù)庫(kù)被映射為auth_group數(shù)據(jù)表。
分組操作:
Group.object.create(group_name):創(chuàng)建分組。
group.permissions:某個(gè)分組上的權(quán)限。多對(duì)多的關(guān)系。
group.permissions.add:添加權(quán)限。
group.permissions.remove:移除權(quán)限。
group.permissions.clear:清除所有權(quán)限。
user.get_group_permissions():獲取用戶所屬組的權(quán)限。
user.groups:某個(gè)用戶上的所有分組。多對(duì)多的關(guān)系。
我們首先新建一個(gè)分組:
from django.contrib.auth.models import Permission,ContentType,Group from .models import Article def operate_group(request): group = Group.objects.create(name='運(yùn)營(yíng)') # 額到Article這個(gè)模型的content_type_id content_type = ContentType.objects.get_for_model(Article) permissions = Permission.objects.filter(content_type=content_type) group.permissions.set(permissions) return HttpResponse('操作分組')
這里我們就創(chuàng)建了一個(gè)運(yùn)營(yíng)的分組,并且將Article這個(gè)模型所有的權(quán)限都添加進(jìn)去了。
然后我們可以查看我們的數(shù)據(jù)庫(kù)中我們添加的信息。在表auth_group和auth_group_permissions中,因?yàn)間roup和permissions是一個(gè)多對(duì)多的關(guān)系,所以它們擁有一個(gè)中間表。
我們創(chuàng)建好了一個(gè)組,那么我們就需要添加一個(gè)用戶進(jìn)去了。
修改上面的函數(shù)為:
def operate_group(request): # group = Group.objects.create(name='運(yùn)營(yíng)') # # 額到Article這個(gè)模型的content_type_id # content_type = ContentType.objects.get_for_model(Article) # permissions = Permission.objects.filter(content_type=content_type) # group.permissions.set(permissions) group = Group.objects.filter(name='運(yùn)營(yíng)').first() user = User.objects.first() user.groups.add(group) user.save() return HttpResponse('操作分組')
這樣,我們就對(duì)運(yùn)營(yíng)這個(gè)組添加了一個(gè)用戶進(jìn)去了。
判斷某個(gè)group下的某個(gè)用戶的所有權(quán)限:
def operate_group(request): # group = Group.objects.create(name='運(yùn)營(yíng)') # # 額到Article這個(gè)模型的content_type_id # content_type = ContentType.objects.get_for_model(Article) # permissions = Permission.objects.filter(content_type=content_type) # group.permissions.set(permissions) # group = Group.objects.filter(name='運(yùn)營(yíng)').first() # user = User.objects.first() # user.groups.add(group) # user.save() user = User.objects.first() permissions = user.get_group_permissions() print(permissions) return HttpResponse('操作分組')
在模板中使用權(quán)限:
在settings.TEMPLATES.OPTIONS.context_processors下,因?yàn)樘砑恿薲jango.contrib.auth.context_processors.auth上下文處理器,因此在模板中可以直接通過(guò)perms來(lái)獲取用戶的所有權(quán)限。
我們新建一個(gè)index.html的文件,然后渲染一下這個(gè)頁(yè)面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>首頁(yè)</h1> {#如果擁有這個(gè)權(quán)限,我就顯示這個(gè)標(biāo)簽#} {% if perms.authority.add_article %} <a href="#" rel="external nofollow" >添加文章</a> {% endif %} </body> </html>
然后新建一個(gè)視圖來(lái)渲染這個(gè)頁(yè)面:
def index(request): return render(request,'index.html')
然后添加url,就可以了。當(dāng)我們沒(méi)有登錄的時(shí)候,也不會(huì)顯示出來(lái)。
以上這篇對(duì)Django中的權(quán)限和分組管理實(shí)例講解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
django使用django-apscheduler 實(shí)現(xiàn)定時(shí)任務(wù)的例子
今天小編就為大家分享一篇django使用django-apscheduler 實(shí)現(xiàn)定時(shí)任務(wù)的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07淺談使用Python變量時(shí)要避免的3個(gè)錯(cuò)誤
這篇文章主要介紹了淺談使用Python變量時(shí)要避免的3個(gè)錯(cuò)誤,還是比較不錯(cuò)的,涉及部分代碼分析,以及字典的創(chuàng)建等相關(guān)內(nèi)容,需要的朋友可以參考下。2017-10-10Python使用Pandas處理測(cè)試數(shù)據(jù)的方法
Pandas是一個(gè)功能極其強(qiáng)大的數(shù)據(jù)分析庫(kù),可以高效地操作各種數(shù)據(jù)集,這篇文章主要介紹了Python自動(dòng)化測(cè)試-使用Pandas來(lái)高效處理測(cè)試數(shù)據(jù),需要的朋友可以參考下2023-02-02Python 格式化打印json數(shù)據(jù)方法(展開(kāi)狀態(tài))
今天小編就為大家分享一篇Python 格式化打印json數(shù)據(jù)方法(展開(kāi)狀態(tài)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02Python實(shí)現(xiàn)爬取需要登錄的網(wǎng)站完整示例
這篇文章主要介紹了Python實(shí)現(xiàn)爬取需要登錄的網(wǎng)站,結(jié)合完整實(shí)例形式分析了Python登陸網(wǎng)站及數(shù)據(jù)抓取相關(guān)操作技巧,需要的朋友可以參考下2017-08-08Python實(shí)現(xiàn)FTP上傳文件或文件夾實(shí)例(遞歸)
本篇文章主要介紹了Python實(shí)現(xiàn)FTP上傳文件或文件夾實(shí)例(遞歸),具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01Python小程序編程實(shí)現(xiàn)一鍵自動(dòng)整理文件解壓文件
這篇文章主要為大家介紹了Python小程序編程實(shí)現(xiàn)一鍵自動(dòng)整理文件解壓文件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Python configparser模塊操作代碼實(shí)例
這篇文章主要介紹了Python configparser模塊操作代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06pandas pivot_table() 按日期分多列數(shù)據(jù)的方法
今天小編就為大家分享一篇pandas pivot_table() 按日期分多列數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11