day08-Django-用户权限,用户角色使用指南

前言(借鉴老师笔记)

RBAC(Role-Based Access Control,基于角色的访问控制)就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。

简单的权限:如下就是一个简单的权限设计模式,其中包含了用户表,角色表,权限表。

图片.png

稍微复杂一点的权限,可能设计到用户表、权限表、角色表、用户组表、额外的权限表,在django中提供了这一些列的权限相关模型,关于权限设计中表的关联关系如下:

图片.png

)

1. Django的权限项

Django用permission对象存储权限项,每个model默认都有三个permission,即add model, change model和delete model。例如,定义一个名为学生Student模型,当迁移表后,会在auth_permission中自动创建相应的三个permission:add_student, change_student和delete_student。Django还允许自定义permission。

图片.png

2. 创建权限

1) 自定义权限

在自定义模型的Meta元中添加permissions参数,自定义权限的名称(‘codename’,‘name’)即codename为权限名,name为权限的描述。在数据库的auth_permission表中还有一个content_type字段,其表示prmission属于哪个model

from django.db import models

class Users(AbstractUser):
    """
    管理员---拓展User表
    """
    class Meta:
        permissions = (
            ('add_user_per', '添加用户权限'),
            ('del_user_per', '删除用户权限'),
            ('change_user_per', '修改用户权限'),
            ('sel_user_per', '查询用户权限')
        )

并在settings.py文件中添加如下设置:

AUTH_USER_MODEL = 'users.Users'

注意:在数据库的auth_permission表中,会新增权限,包括自带的对Users管理的权限,和自定义的四个权限。

如下所示:

[图片上传失败...(image-ee6095-1537444192584)]

2)创建权限

上面的方法是在定义模型的时候自定义权限,也可理解为创建系统的内置权限,如果涉及到在业务逻辑中创建权限,则可以通过Permission模型来创建权限

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':
        # 获取当前Users模型的id值
        content_type = ContentType.objects.get_for_model(Users)
        # codename为权限名,name为描述,content_type为当前权限属于哪一个模型的ID
        Permission.objects.create(codename='add_other_user_permission',
                                  name='添加其他用户权限',
                                  content_type=content_type)
        return HttpResponse('创建权限成功')

3.分配权限

1)给用户直接添加某种权限

采用直接分配权限的方法,给用户添加额外的权限既用户表Users和权限Permission模型以及中间表user_permission之间的关联关系。用户Users模型和权限Permission之间是ManyToManyField()多对多关联关系,关联字段为user_permission。

语法:

添加权限:user对象.user_permission.add(permission对象1, permission对象2)

删除权限:user对象.user_permission.remove(permission对象1, permission对象2)

清空权限: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)
        # 给该用户添加权限
        pers = Permission.objects.filter(codename__in=['add_user_per', 'del_user_per'])
        for per in pers:
            # 添加用户权限
            user.user_permissions.add(per)
            #删除权限
            # user.user_permissions.remove(per)
        # 清空权限
        user.user_permissions.clear()
        return HttpResponse('创建权限成功')

2)创建组并分配对应组的权限

给组添加权限,涉及到组group表和permission权限表,以及中间关联表。其为ManyToManyFiled()关联关系,关联字段为permissions 语法:

添加权限:group对象.permissions.add(permission对象1, permission对象2)

删除权限:group对象.permissions.remove(permission对象1, permission对象2)

清空权限:group对象.permissions.clear()

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

def group_permission(request):
    if request.method == 'GET':
        # 创建超级管理用户组并给用户组增加对用户进行CRUD的权限
        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:
            # 添加超级用户组的权限
            super_group.permissions.add(per)
            # 删除超级组的权限
            super_group.permissions.remove(per)
        # 清空组的权限
        super_group.permissions.clear()
        return HttpResponse('创建组权限')

3)分配用户和权限组

给用户添加组权限,涉及到组group表和user用户表,以及中间关联表。其为ManyToManyFiled()关联关系,关联字段为groups 语法:

添加权限:user对象.groups.add(groups对象1, groups对象2)

删除权限:user对象.groups.remove(groups对象1, groups对象2)

清空权限:user对象.groups.clear()

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

def user_group(request):
    if request.method == 'GET':
        # 给id为1的用户分配超级管理员组的权限
        # 获取超级管理员组group对象
        super_group = Group.objects.get(name='超级管理员')
        # 获取id=1d的用户对象
        user = Users.objects.get(id=1)
        # 添加超级用户组的权限
        user.groups.add(super_group)
        # 删除超级组的权限
        # user.groups.remove(super_group)
        # 清空组的权限
        # user.groups.clear()
        return HttpResponse('创建用户组权限')

4. 检测用户是否有某权限,和所有权限,组权限

语法:用户对象.has_perm('模型名.权限codename')

查询用户所有的权限:user.get_all_permissions()方法列出用户的所有权限,返回值是permission name

查询用户的组权限:user.get_group_permissions()方法列出用户所属group的权限,返回值是permission name

def user_permission(request):
    if request.method == 'GET':
        # 获取id=1d的用户对象
        user = Users.objects.get(id=1)
        # 查看用户的所有权限
        all_perm = user.get_all_permissions()
        # 查看用户的组权限
        group_perm = user.get_group_permissions()
        # 查询用户是否有add_user_per权限
        if user.has_perm('users.add_user_per'):
            return HttpResponse('用户有add_user_per权限')
        else:
            return HttpResponse('用户没有add_user_per权限')

5. 权限校验,使用permission_required装饰器

使用permission_required对权限进行校验,如果没有当前登录系统的用户没有该权限则跳转到登录页面,如果当前用户有该权限,则进行访问对应的视图函数。

语法:@permission_required('应用app名.权限名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('该方法需要添加用户权限才可访问')

6. 测试

定义登录的路由,并实现登录操作,当用户登录后,再次访问add_user_html路由地址,则可以访问到对应的视图函数,如果用户没有登录则因为权限问题访问不了add_user_html路由对应的视图函数。

7. 首页index.html中通过权限控制按钮

在模版中使用:模版中使用全局变量perms存储当前用户的所有权限。通过{{ perms.应用名 }}可打印出所有的权限。

在模板中也可以直接通过{{ user }}获取当前登录系统的用户信息。

使用语法格式:

{% if perms.应用名.权限标识 %}
    <!-- 这里是有权限才显示的内容 -->
{% endif %}

首页index.html中如下控制按钮的权限:

{% extends 'base.html' %}

{% block title %}
    首页
{% endblock %}

{% block content %}

    <!--模版中使用全局变量perms存储当前用户的所有权限-->
    {{ perms.users }}
    <!--判断当前用户是否为超级管理员-->
    {{ 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 %}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • Django权限系统auth模块详解 auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用...
    梦Delete阅读 1,218评论 0 0
  • 经过对django的初步学习,我们已经对后台的基本流程以及django的运作有了一定的了解,但是这还不足够,dja...
    coder_ben阅读 3,827评论 8 34
  • cms_project 项目,自定义用户和相关权限设置 1.重写用户模型 1.1 修改配置文件,覆盖默认的User...
    常大鹏阅读 25,821评论 1 26
  • django——重写用户模型 Django内建的User模型可能不适合某些类型的项目。例如,在某些网站上使用邮件地...
    常大鹏阅读 26,300评论 2 29
  • 01 温暖的阳光下,我和父亲在聊天。父亲说:做人要厚道,要宽容。我似懂非懂,接着他讲了一个故事。 因为做生意,经常...
    寒山红枫阅读 435评论 0 1