演示Django版本爲當前最新版本v2.2html
當Django配置文件中的INSTALL_APPS
包含了django.contrib.auth
時,就默認啓用了一個簡單的權限系統,提供了爲用戶或組分配權限的方法前端
之因此說簡單呢?主要是由於:git
也就是說,假若有一個Blog表,咱們能夠賦予用戶或組對Blog表有delete的權限,那麼用戶或組成員就能夠刪除所有Blog,是不能控制用戶只能刪除本身建立的blog的github
若是但願用戶只能刪除本身建立的Blog,不能刪除別人建立的Blog,這種需求Django默認的權限管理就沒法實現了,須要用到object permission
對象權限,有第三方模塊實現了對象權限,如django-guardian,你能夠直接使用,或者也能夠本身實現對象權限,具體思路可參考這篇文章:Django內置權限擴展案例django
add_
、修改change_
、刪除delete_
、查看view_
,這些權限記錄在Permission表中,表數據以下:默認權限的建立是經過Django的信號signals實現的,使用了post_migrate
信號,在每次執行migrate操做時都會爲新的Model模型建立默認權限,關於Django的信號Signals介紹和使用能夠查看這篇文章:Django使用Signals監測model字段變化發送通知,後端
默認的權限名字和描述都是英文的,且只有四個,若是你不想用默認的幾個權限,想要自定義的話,能夠這樣作:架構
class Blog(models.Model): title = models.CharField(max_length=256, verbose_name='標題') content = models.TextField(blank=True, null=True, verbose_name='內容') class Meta: default_permissions = () permissions = ( ("change_blog", "修改博客"), ("delete_blog", "查看博客"), ("publish_blog", "發佈博客"), )
default_permissions: 清空默認的權限app
permissions: 設置權限,內容是一個嵌套的列表,列表第一個字段是codename
,第二個字段爲name
工具
注意:若是你使用了django默認的admin的話,建議保留4個默認權限,能夠添加新權限post
若是你用了Django自帶的admin,在migrate以後就能在admin的user和group兩個表中看到新添加的權限了
固然你也能夠在程序中來添加或修改權限
ops = User.objects.get(id=2) ops.user_permissions.add(25, 26) ops.user_permissions.set([26, 27]) ops.user_permissions.remove(26, 27) ops.user_permissions.clear()
coffee = Group.objects.get(id=1) coffee.permissions.add(25) coffee.permissions.set([26,27]) coffee.permissions.remove(25) coffee.permissions.clear()
其中add
爲添加,set
爲設置,remove
爲移除,clear
爲清空,add
跟set
的區別是add
會在原有權限的基礎上加新權限,而set
會清空原有權限設置成新的權限,後邊的參數25,26,27能夠爲Permission的ID或者是Permission對象,例如這樣也是能夠的:
p = Permission.objects.get(id=25) coffee.permissions.add(p)
給組賦予權限,組內的全部用戶會自動的擁有該組的權限,例如用戶ops-coffee
隸屬於組SRE
,SRE
組對Blog表有修改權限,那麼即使是沒有單獨給Y37
用戶分配任何權限,他也會有對Blog表的修改權限
get_all_permissions()
列出用戶的全部權限:
>>> User.objects.get(username='ops-coffee').get_all_permissions() {'blog.publish_blog', 'blog.delete_blog', 'auth.add_group', 'blog.change_blog'}
get_group_permissions()
列出用戶所屬組的權限:
>>> User.objects.get(username='ops-coffee').get_group_permissions() {'blog.publish_blog', 'blog.change_blog', 'blog.delete_blog'}
用戶對象能夠經過has_perm
方法來判斷用戶是否擁有某個權限:
>>> User.objects.get(username='ops-coffee').has_perm('blog.change_blog') True >>> User.objects.get(username='ops-coffee').has_perm('blog.delete_blog') True
has_perm 的參數由<app label>.<permission codename>
兩部分組成,例如blog.delete_blog
表示的就是名字爲blog
的APP下的delete_blog
權限
能夠直接在view中經過if判斷用戶權限,例如:
def ops_coffee_view(request): if not request.user.has_perm('blog.change_blog') return HttpResponse('403 Forbidden')
爲了方便,Django還提供了一個permission_required()
的裝飾器,能夠快速的來校驗用戶是否擁有特定的權限,用法以下:
@permission_required(perm, login_url=None, raise_exception=False)
三個參數的意思分別是:
perm: 必須有,權限名稱,同has_perm
同樣
login_url: 非必須,登錄的url地址,當你沒有權限時自動跳轉到登錄頁,這裏能夠設置登錄地址的url
reise_exception: 非必須,當爲True時,若是用戶沒有權限,則不會跳轉到登錄頁,而是引起PermissionDenied
錯誤,返回403 Forbidden
以下例子,判斷用戶是否有blog
的APP的change_blog
權限,若是沒有則返回403錯誤
@permission_required('blog.change_blog', raise_exception=True) def ops_coffee_view(request): ...
當前登錄用戶的權限保存在模版變量{{ perms }}
中,能夠在模版中經過if判斷用戶是否擁有相應的權限而開放對應的內容,例如對於側邊欄菜單隻顯示用戶有權限訪問的,就能夠這麼寫:
{% if perms.cmdb.view_project %} <li><a href="{% url 'project-list-url' %}"></i> 項目列表</a></li> {% endif %} {% if perms.cmdb.view_service %} <li><a href="{% url 'service-list-url' %}"></i> 服務列表</a></li> {% endif %} {% if perms.cmdb.view_environment %} <li><a href="{% url 'environment-list-url' %}"></i> 環境列表</a></li> {% endif %}
至此,Django的默認權限系統介紹完成,默認權限在小型項目中能知足大部分的需求,若是對權限控制有更高的要求能夠關注前文中介紹的django-guardian
項目或本身實現
相關文章推薦閱讀:
原文出處:https://www.cnblogs.com/37Y37/p/11658651.html