day08-Django-用戶權(quán)限,用戶角色使用指南

前言(借鑒老師筆記)

RBAC(Role-Based Access Control,基于角色的訪問控制)就是用戶通過角色與權(quán)限進行關(guān)聯(lián)。簡單地說,一個用戶擁有若干角色,每一個角色擁有若干權(quán)限。這樣,就構(gòu)造成“用戶-角色-權(quán)限”的授權(quán)模型。在這種模型中,用戶與角色之間,角色與權(quán)限之間,一般者是多對多的關(guān)系。

簡單的權(quán)限:如下就是一個簡單的權(quán)限設(shè)計模式,其中包含了用戶表,角色表,權(quán)限表。

圖片.png

稍微復(fù)雜一點的權(quán)限,可能設(shè)計到用戶表、權(quán)限表、角色表、用戶組表、額外的權(quán)限表,在django中提供了這一些列的權(quán)限相關(guān)模型,關(guān)于權(quán)限設(shè)計中表的關(guān)聯(lián)關(guān)系如下:

圖片.png

)

1. Django的權(quán)限項

Django用permission對象存儲權(quán)限項,每個model默認(rèn)都有三個permission,即add model, change model和delete model。例如,定義一個名為學(xué)生Student模型,當(dāng)遷移表后,會在auth_permission中自動創(chuàng)建相應(yīng)的三個permission:add_student, change_student和delete_student。Django還允許自定義permission。

圖片.png

2. 創(chuàng)建權(quán)限

1) 自定義權(quán)限

在自定義模型的Meta元中添加permissions參數(shù),自定義權(quán)限的名稱(‘codename’,‘name’)即codename為權(quán)限名,name為權(quán)限的描述。在數(shù)據(jù)庫的auth_permission表中還有一個content_type字段,其表示prmission屬于哪個model

from django.db import models

class Users(AbstractUser):
    """
    管理員---拓展User表
    """
    class Meta:
        permissions = (
            ('add_user_per', '添加用戶權(quán)限'),
            ('del_user_per', '刪除用戶權(quán)限'),
            ('change_user_per', '修改用戶權(quán)限'),
            ('sel_user_per', '查詢用戶權(quán)限')
        )

并在settings.py文件中添加如下設(shè)置:

AUTH_USER_MODEL = 'users.Users'

注意:在數(shù)據(jù)庫的auth_permission表中,會新增權(quán)限,包括自帶的對Users管理的權(quán)限,和自定義的四個權(quán)限。

如下所示:

[圖片上傳失敗...(image-ee6095-1537444192584)]

2)創(chuàng)建權(quán)限

上面的方法是在定義模型的時候自定義權(quán)限,也可理解為創(chuàng)建系統(tǒng)的內(nèi)置權(quán)限,如果涉及到在業(yè)務(wù)邏輯中創(chuàng)建權(quán)限,則可以通過Permission模型來創(chuàng)建權(quán)限

url(r'^add_user_permission/', views.add_user_permission,name='add_user_permission'),

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

from users.models import Users

def add_user_permission(request):
    if request.method == 'GET':
        # 獲取當(dāng)前Users模型的id值
        content_type = ContentType.objects.get_for_model(Users)
        # codename為權(quán)限名,name為描述,content_type為當(dāng)前權(quán)限屬于哪一個模型的ID
        Permission.objects.create(codename='add_other_user_permission',
                                  name='添加其他用戶權(quán)限',
                                  content_type=content_type)
        return HttpResponse('創(chuàng)建權(quán)限成功')

3.分配權(quán)限

1)給用戶直接添加某種權(quán)限

采用直接分配權(quán)限的方法,給用戶添加額外的權(quán)限既用戶表Users和權(quán)限Permission模型以及中間表user_permission之間的關(guān)聯(lián)關(guān)系。用戶Users模型和權(quán)限Permission之間是ManyToManyField()多對多關(guān)聯(lián)關(guān)系,關(guān)聯(lián)字段為user_permission。

語法:

添加權(quán)限:user對象.user_permission.add(permission對象1, permission對象2)

刪除權(quán)限:user對象.user_permission.remove(permission對象1, permission對象2)

清空權(quán)限:user對象.user_permission.clear()

url(r'^add_permission/', views.add_permission, name='add_permission'),

from django.contrib.auth.models import Permission, User

def add_permission(request):
    if request.method == 'GET':
        # 獲取id=1d的用戶對象
        user = Users.objects.get(id=1)
        # 給該用戶添加權(quán)限
        pers = Permission.objects.filter(codename__in=['add_user_per', 'del_user_per'])
        for per in pers:
            # 添加用戶權(quán)限
            user.user_permissions.add(per)
            #刪除權(quán)限
            # user.user_permissions.remove(per)
        # 清空權(quán)限
        user.user_permissions.clear()
        return HttpResponse('創(chuàng)建權(quán)限成功')

2)創(chuàng)建組并分配對應(yīng)組的權(quán)限

給組添加權(quán)限,涉及到組group表和permission權(quán)限表,以及中間關(guān)聯(lián)表。其為ManyToManyFiled()關(guān)聯(lián)關(guān)系,關(guān)聯(lián)字段為permissions 語法:

添加權(quán)限:group對象.permissions.add(permission對象1, permission對象2)

刪除權(quán)限:group對象.permissions.remove(permission對象1, permission對象2)

清空權(quán)限:group對象.permissions.clear()

url(r'^group_permission/', views.group_permission, name='group_permission'),

def group_permission(request):
    if request.method == 'GET':
        # 創(chuàng)建超級管理用戶組并給用戶組增加對用戶進行CRUD的權(quán)限
        super_group = Group.objects.create(name='超級管理員')
        pers = Permission.objects.filter(codename__in=['add_user_per', 'del_user_per', 'change_user_per', 'sel_user_per'])
        for per in pers:
            # 添加超級用戶組的權(quán)限
            super_group.permissions.add(per)
            # 刪除超級組的權(quán)限
            super_group.permissions.remove(per)
        # 清空組的權(quán)限
        super_group.permissions.clear()
        return HttpResponse('創(chuàng)建組權(quán)限')

3)分配用戶和權(quán)限組

給用戶添加組權(quán)限,涉及到組group表和user用戶表,以及中間關(guān)聯(lián)表。其為ManyToManyFiled()關(guān)聯(lián)關(guān)系,關(guān)聯(lián)字段為groups 語法:

添加權(quán)限:user對象.groups.add(groups對象1, groups對象2)

刪除權(quán)限:user對象.groups.remove(groups對象1, groups對象2)

清空權(quán)限:user對象.groups.clear()

url(r'^user_group/', views.user_group, name='user_group'),

def user_group(request):
    if request.method == 'GET':
        # 給id為1的用戶分配超級管理員組的權(quán)限
        # 獲取超級管理員組group對象
        super_group = Group.objects.get(name='超級管理員')
        # 獲取id=1d的用戶對象
        user = Users.objects.get(id=1)
        # 添加超級用戶組的權(quán)限
        user.groups.add(super_group)
        # 刪除超級組的權(quán)限
        # user.groups.remove(super_group)
        # 清空組的權(quán)限
        # user.groups.clear()
        return HttpResponse('創(chuàng)建用戶組權(quán)限')

4. 檢測用戶是否有某權(quán)限,和所有權(quán)限,組權(quán)限

語法:用戶對象.has_perm('模型名.權(quán)限codename')

查詢用戶所有的權(quán)限:user.get_all_permissions()方法列出用戶的所有權(quán)限,返回值是permission name

查詢用戶的組權(quán)限:user.get_group_permissions()方法列出用戶所屬group的權(quán)限,返回值是permission name

def user_permission(request):
    if request.method == 'GET':
        # 獲取id=1d的用戶對象
        user = Users.objects.get(id=1)
        # 查看用戶的所有權(quán)限
        all_perm = user.get_all_permissions()
        # 查看用戶的組權(quán)限
        group_perm = user.get_group_permissions()
        # 查詢用戶是否有add_user_per權(quán)限
        if user.has_perm('users.add_user_per'):
            return HttpResponse('用戶有add_user_per權(quán)限')
        else:
            return HttpResponse('用戶沒有add_user_per權(quán)限')

5. 權(quán)限校驗,使用permission_required裝飾器

使用permission_required對權(quán)限進行校驗,如果沒有當(dāng)前登錄系統(tǒng)的用戶沒有該權(quán)限則跳轉(zhuǎn)到登錄頁面,如果當(dāng)前用戶有該權(quán)限,則進行訪問對應(yīng)的視圖函數(shù)。

語法:@permission_required('應(yīng)用app名.權(quán)限名codename')

url(r'^add_user_html/', views.add_user_html, name='add_user_html'),

from django.contrib.auth.decorators import permission_required

@permission_required('users.add_users')
def add_user_html(request):
    if request.method == 'GET':
        return HttpResponse('該方法需要添加用戶權(quán)限才可訪問')

6. 測試

定義登錄的路由,并實現(xiàn)登錄操作,當(dāng)用戶登錄后,再次訪問add_user_html路由地址,則可以訪問到對應(yīng)的視圖函數(shù),如果用戶沒有登錄則因為權(quán)限問題訪問不了add_user_html路由對應(yīng)的視圖函數(shù)。

7. 首頁index.html中通過權(quán)限控制按鈕

在模版中使用:模版中使用全局變量perms存儲當(dāng)前用戶的所有權(quán)限。通過{{ perms.應(yīng)用名 }}可打印出所有的權(quán)限。

在模板中也可以直接通過{{ user }}獲取當(dāng)前登錄系統(tǒng)的用戶信息。

使用語法格式:

{% if perms.應(yīng)用名.權(quán)限標(biāo)識 %}
    <!-- 這里是有權(quán)限才顯示的內(nèi)容 -->
{% endif %}

首頁index.html中如下控制按鈕的權(quán)限:

{% extends 'base.html' %}

{% block title %}
    首頁
{% endblock %}

{% block content %}

    <!--模版中使用全局變量perms存儲當(dāng)前用戶的所有權(quán)限-->
    {{ perms.users }}
    <!--判斷當(dāng)前用戶是否為超級管理員-->
    {{ user.is_superuser }}

    {% if user.is_superuser or perms.users.add_user_per %}
        <p>添加用戶管理</p>
    {% endif %}
    {% if user.is_superuser or perms.users.del_user_per %}
        <p>刪除用戶管理</p>
    {% endif %}
    {% if user.is_superuser or perms.users.change_user_per %}
        <p>修改用戶管理</p>
    {% endif %}
    {% if user.is_superuser or perms.users.sel_user_per %}
        <p>查詢用戶管理</p>
    {% endif %}
{% endblock %}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Django權(quán)限系統(tǒng)auth模塊詳解 auth模塊是Django提供的標(biāo)準(zhǔn)權(quán)限管理系統(tǒng),可以提供用戶身份認(rèn)證, 用...
    夢Delete閱讀 1,273評論 0 0
  • 經(jīng)過對django的初步學(xué)習(xí),我們已經(jīng)對后臺的基本流程以及django的運作有了一定的了解,但是這還不足夠,dja...
    coder_ben閱讀 3,956評論 8 34
  • cms_project 項目,自定義用戶和相關(guān)權(quán)限設(shè)置 1.重寫用戶模型 1.1 修改配置文件,覆蓋默認(rèn)的User...
    常大鵬閱讀 25,974評論 1 26
  • django——重寫用戶模型 Django內(nèi)建的User模型可能不適合某些類型的項目。例如,在某些網(wǎng)站上使用郵件地...
    常大鵬閱讀 26,546評論 2 29
  • 01 溫暖的陽光下,我和父親在聊天。父親說:做人要厚道,要寬容。我似懂非懂,接著他講了一個故事。 因為做生意,經(jīng)常...
    寒山紅楓閱讀 529評論 0 1

友情鏈接更多精彩內(nèi)容