許可(Permissions)和用戶組(Group)

Django 用 user吟孙、group 和 permission 完成了權限機制,這個權限機制是將屬于 model 的某個 permission 賦予 user 或 group料按,可以理解為全局的權限

即如果用戶 A 對數(shù)據(jù)模型(model)B 有可寫權限卓箫,那么 A 能修改 model B 的所有實例(objects)载矿。group 的權限也是如此,如果為 group C 賦予 model B 的可寫權限烹卒,則隸屬于 group C 的所有用戶闷盔,都可以修改 model B 的所有實例。




1.Django的權限項

Django 用 permission 對象存儲權限項旅急,每個 model 默認都有三個 permission逢勾,即 add、change 和 delete藐吮。

我們在 Django 項目里創(chuàng)建一個叫 myApp 的 app敏沉,然后在 modles 添加一個 Book 模型:

from django.db import models

class Book(models.Model):
    title = models.CharField(null=True, blank=True, max_length=200)

    def __str__(self):
        return self.title

打開 admin 可以在 user 的管理界面看到 Book 的三個 permission:

因為在定義好 Book 之后,Django 會自動創(chuàng)建相應的三個 permission:add_book炎码、change_bookdelete_book

每個 permission 都是 django.contrib.auth.Permission 類型的實例秋泳,該類型包含三個字段 name, codenamecontent_type潦闲。

  • content_type 反應了 permission 屬于哪個 model(如:Book)
  • codename 是代碼邏輯中檢查權限時要用(如:'add_book')
  • name 是 permission 的描述,將 permission 打印到屏幕或頁面時默認顯示的就是name(如:Can add book)

我們可以用 has_perm() 方法來檢驗某個用戶是否用于某種權限:

from django.contrib.auth.models import User

u = User.objects.get(username='diego')

# has_perm 的 參數(shù)格式是: 'app_label.codename'
>>> u.has_perm('myApp.add_book')
True

>>> u.has_perm('myApp.change_book')
True

>>> u.has_perm('myApp.delete_book')
True

可見超級用戶 diego 擁有對 Book 模型的所有對象進行 add迫皱、change歉闰、delete 操作的權限。




2.用戶權限管理

我們再創(chuàng)建一個普通的用戶 test_user卓起,然后檢測下它的權限:

u = User.objects.get(username='test_user')

>>> u.has_perm('myApp.add_book')
False

>>> u.has_perm('myApp.change_book')
False

>>> u.has_perm('myApp.delete_book')
False

新創(chuàng)建的普通用戶并沒有對 Book 對象 add和敬、change、delete 的權限戏阅,現(xiàn)在我們來給用戶 test_user 增加權限:

# 用戶模型昼弟、權限模型
from django.contrib.auth.models import User, Permission

u = User.objects.get(username='test_user')

# 通過 codename 找到對應的權限
permission = Permission.objects.get(codename='change_book')

# 把權限賦予給該用戶
u.user_permissions.add(permission)

>>> u.has_perm('myApp.change_book')
True

同理,還可以對用戶權限進行其他操作:

# 設置權限
myuser.user_permissions = [permission_list]

# 設置權限
myuser.user_permissions.set([permission_list])

#增加權限
myuser.user_permissions.add(permission, permission, ...)

#刪除權限
myuser.user_permissions.remove(permission, permission, ...) 

#清空權限
myuser.user_permissions.clear()


# 注意:myuser 是一個用戶對象奕筐,permission 是一個權限對象




3.自定義權限

Django 還允許自定義 permission舱痘,例如变骡,我們可以為 Book 創(chuàng)建新的權限項:read_book, vote_book(參見豆瓣:讀過、評分)等等芭逝。

現(xiàn)在我們?yōu)?Book 模型增加兩項新的 permission塌碌,分別為 read_book 和 vote_book:

from django.db import models

class Book(models.Model):
    title = models.CharField(null=True, blank=True, max_length=200)

    def __str__(self):
        return self.title

    class Meta:
        # 自定義的權限,兩參數(shù)分別是權限的名字和權限的描述
        permissions = (
            ("read_book", "Can Read Book"),
            ("vote_book", "Can Vote Book"),
        )

再打開 admin 檢查旬盯,可以看到剛才新增加的:

再做個測試:

u = User.objects.get(username='diego')

>>> u.has_perm('myApp.read_book')
True

>>> u.has_perm('myApp.vote_book')
True

超級管理員同樣擁有新增加的 permission台妆。

附注:

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

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




4.組別(Group)

用戶組模型很簡單接剩,和 User 模型是多對多的關系。用戶組顧名思義泡态,就是對用戶進行了分組搂漠。其作用在權限控制中就是可以批量的對用戶的許可進行分配,而不用一個一個的按用戶分配某弦,節(jié)省維護的工作量桐汤。

將一個用戶加入到一個 Group 中,該用戶就擁有了該 Group 所分配的所有許可靶壮。例如怔毛,如果一個組 reader 有權限 read_book 和 vote_book。那么所有屬于 reader 組的用戶都會有這個權限腾降。

下面我們創(chuàng)建一個新分組 reader拣度,再把某用戶加入到該組,再給該組添加上權限:

# 創(chuàng)建一個分組
Group.objects.create(name='reader')

# 獲取某用戶
u = User.objects.get(username='test_user')

# 獲取某分組
g = Group.objects.get(name='reader')

# 把用戶加入到分組中
u.groups.add(g)

# 獲取某個權限
p= Permission.objects.get(codename='read_book')

# 把該權限加入到分組
g.permissions.add(p)

Group 還有其他操作:

# 把用戶加入分組螃壤,group_list可以是一個或多個分組
u.groups = [group_list]

# 把用戶加入某分組
u.groups.add(group, group, ...)

# 把某用戶從某分組刪除
u.groups.remove(group, group, ...)

# 該用戶退出所以分組
u.groups.clear()

# 把權限加入到該分組
g.permissions.add(permission, permissions, ...)

# 從該分組刪除某權限
g.permissions.remove(permission, permissions, ...)

# 清除該分組所以權限
g.permissions.clear()




5.permission_required 裝飾器

使用了permission_required 裝飾器之后抗果,Django 會檢查用戶是否擁有指定的 permission,有相應 permission 的用戶才能訪問該頁面:

from django.contrib.auth.decorators import permission_required

# 圖書閱覽頁面
# 需要有權限 book.read_book 才訪問該頁面
# 否則跳轉(zhuǎn)到 user_login 頁
@ permission_required(perm='book.read_book', login_url="/user_login/")
def read_book(request, id):
    context = {}
    book = Book.objects.get(id=id)
    context['book'] = book
    return render(request, 'read_book.html', context) 




6.Template 中的權限檢查

Template 中使用全局變量 perms 存儲當前用戶的所有權限:

# 以下內(nèi)容只對擁有 vote_book  權限的用戶顯示
{% if perms.myApp.vote_book %}
    <button>打分</button>
{% else %}
    <p>你不能打分</p>
{% endif %}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奸晴,一起剝皮案震驚了整個濱河市冤馏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寄啼,老刑警劉巖逮光,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墩划,居然都是意外死亡涕刚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門乙帮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杜漠,“玉大人,你說我怎么就攤上這事”” “怎么了戴陡?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沟涨。 經(jīng)常有香客問我恤批,道長,這世上最難降的妖魔是什么裹赴? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任喜庞,我火速辦了婚禮,結(jié)果婚禮上棋返,老公的妹妹穿的比我還像新娘延都。我一直安慰自己,他們只是感情好睛竣,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布晰房。 她就那樣靜靜地躺著,像睡著了一般射沟。 火紅的嫁衣襯著肌膚如雪殊者。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天验夯,我揣著相機與錄音猖吴,去河邊找鬼。 笑死挥转,一個胖子當著我的面吹牛海蔽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绑谣,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼党窜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了借宵?” 一聲冷哼從身側(cè)響起幌衣,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎暇务,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怔软,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡垦细,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挡逼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片括改。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖家坎,靈堂內(nèi)的尸體忽然破棺而出嘱能,到底是詐尸還是另有隱情吝梅,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布惹骂,位于F島的核電站苏携,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏对粪。R本人自食惡果不足惜右冻,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望著拭。 院中可真熱鬧纱扭,春花似錦、人聲如沸儡遮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鄙币。三九已至肃叶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爱榔,已是汗流浹背被环。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留详幽,地道東北人筛欢。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像唇聘,于是被迫代替她去往敵國和親版姑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容