Django 权限管理和guardian插件

news2024/11/19 11:29:40

内置权限管理

Django内置的权限管理, 是一种表权限, 就是可分别配置某管理员用户对某个表的全部数据有没有增删改查4种权限.

图形界面配置权限

之前提到,使用命令行创建超管用户:

python manage.py createsuperuser

这其实是在最普通的用户的基础上将is_superuseris_staffis_active三个属性设为True,在管理界面的首页 › 认证和授权 › 用户可找到用户详情页,会发现超管用户的权限属性如下:

Image

并且在用户权限中,超管用户拥有所有可设置的权限(所有模型表的增删改查)。

首页 › 认证和授权 › 用户中可添加用户,并且可以用图形界面配置新用户的权限,以及权限组都可以用图形界面。

Image

代码创建用户并配置权限

用代码可以自动、批量创建用户。可以用django-shell, 也可写入文件。 以django-shell为例, 先在项目目录运行django-shell:python manage.py shell, 然后运行:

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

user = User.objects.create_user( username='jam123', password='12345678', is_staff=True, first_name='jam')

以上代码可创建一个管理员用户, 可以登录后台, 但目前还无任何权限. 权限本身就是多对多关联对象, 配置方法与多对多关联关系一样:

from django.db.models.query_utils import Q
user.user_permissions.add( *Permission.objects.filter( Q(codename__startswith='view')| Q(codename__startswith='delete')))

codename一般写为以add、change、delete、view开头,后接下划线加表名小写,例如add_user__startswith代表以什么字符开头. 所以以上代码可给刚刚创建的用户赋予“查看”和“删除”所有模型表内所有对象的权限.

guardian插件

Django框架的一大特色就是有各种各样强大的插件可以选用。 内置的权限管理只能配置表权限,如果要达到“某个管理员控制某个单独对象”的功能,需要安装使用guardian插件。

安装和准备

在有pip的前提下,在项目目录下执行:

pip install django-guardian

安装好后,需要在项目settings.py文件中指定app,在INSTALLED_APPS中这样添加:

INSTALLED_APPS = [
    <!-- 之前的不变 -->
    'guardian',
]

AUTHENTICATION_BACKENDS是指定可以进行权限控制的工具,在其中这样添加:

AUTHENTICATION_BACKENDS = ( 
    'django.contrib.auth.backends.ModelBackend', # 这是Django自带默认的
    'guardian.backends.ObjectPermissionBackend', # 这是guardian的
) 

在admin.py中引入

使用Guardian最直观的特色就是在django-admin页面可以图形化地使用对象权限功能。 首先,在admin.py开头,从guardian添加两个导入:

from guardian.admin import GuardedModelAdminMixin
from guardian.shortcuts import get_objects_for_user, assign_perm

GuardedModelAdminMixin是一个类,包含权限管理的功能,其中Mixin(混入)代表这个类不能单独作为ModelAdmin类使用,需要与其他的ModelAdmin类共同作为子类的父类,新的子类即可既有ModelAdmin的功能也有Guardian权限管理的功能。 但是,GuardedModelAdminMixin本身的功能还是欠缺了点,或者说它本来就是希望开发者自定义重写的。网上有大神将此类继承后重写,完善了其功能,我们将代码抄过来即可(可根据自己项目的特点修改其代码):

class GuardedMixin(GuardedModelAdminMixin):
    # app是否在主页面中显示,由该函数决定
    def has_module_permission(self, request):
        if super().has_module_permission(request):
            return True
        return self.get_model_objs(request,'view').exists()

    # 在显示数据列表时候,哪些数据显示,哪些不显示,由该函数控制
    def get_queryset(self, request):
        if request.user.is_superuser:
            return super().get_queryset(request)
        data = self.get_model_objs(request)
        return data
        
    # 内部用来获取某个用户有权限访问的数据行
    def get_model_objs(self, request, action=None, klass=None):
        opts = self.opts
        actions = [action] if action else ['view', 'change', 'delete']
        klass = klass if klass else opts.model
        model_name = klass._meta.model_name
        data = get_objects_for_user(
            user=request.user, 
            perms=[f'{perm}_{model_name}' for perm in actions],
            klass=klass, any_perm=True
        )
        if hasattr(request.user, 'teacher'):
            data = teacher.objects.filter(id=request.user.teacher.id) | data
        return data
    # 用来判断某个用户是否有某个数据行的权限
    def has_perm(self, request, obj, action):
        opts = self.opts
        codename = f'{action}_{opts.model_name}'
        if hasattr(request.user, 'teacher') and obj == request.user.teacher:
            return True
        if obj:
            return request.user.has_perm(f'{opts.app_label}.{codename}', obj)
        else:
            return self.get_model_objs(request, action).exists()

    # 是否有查看某个数据行的权限
    def has_view_permission(self, request, obj=None):
        return self.has_perm(request, obj, 'view')

    # 是否有修改某个数据行的权限
    def has_change_permission(self, request, obj=None):
        return self.has_perm(request, obj, 'change')

    # 是否有删除某个数据行的权限
    def has_delete_permission(self, request, obj=None):
        return self.has_perm(request, obj, 'delete')

    # 用户应该拥有他新增的数据行的所有权限
    def save_model(self, request, obj, form, change):
        result = super().save_model(request, obj, form, change)
        if not request.user.is_superuser and not change:
            opts = self.opts
            actions = ['view', 'add', 'change', 'delete']
            [assign_perm(f'{opts.app_label}.{action}_{opts.model_name}', request.user, obj) for action in actions]
        return result

当然,这些代码不是尽善尽美的,我们可根据自己项目的特点适当修改这些代码。 而后,将这个我们自己写的GuardedMixin类作为我们自己原来的模型的ModelAdmin类的父类之一:

class TeacherAdmin(GuardedMixin,ModelAdmin):
    # 详情表单页
    inlines = [Class_head_yearInline,FamilyMemberInline]
    fieldsets = [
        # ...

admin.py就编辑完成了,在admin管理页面的Teacher页面中就可以设置某个管理员针对某个teacher对象的权限了。

在图形界面使用

用超级管理员账户,打开某位教师的信息详情页,在右上角出现的“对象权限”按钮,就是我们配置的guardian插件体现的效果。

Image

点击它。

Image

用户身份写入管理员的名字,点击管理用户,便可设置此管理员针对此对象的权限设置,共有增删改查四种设置。

Image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/654003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

百度网盘的最新插件(懂得都懂)

下面先给大家介绍一下油猴插件。 这个插件为什么叫油猴&#xff1f; 现在我们经常提到的油猴插件&#xff0c;常指Tampermonkey&#xff0c;但Tampermonkey翻译过来是叫篡改猴&#xff0c;为什么会叫油猴呢&#xff1f;原因是因为另一个插件Greasemonkey&#xff0c;它翻译过…

Qt编写iFIx组态软件日报表插件的实现

一、iFIx中生成report.MDB文件 在Ifxi组态软件的【调度】中新建调度任务【report】添加【定时器调度项】FixTimer5&#xff0c;间隔1h触发一次。通过此任务及脚本程序&#xff0c;将相关变量定时存入自动生成的report.MDB文件中。 用户脚本程序如下&#xff1a; ---- User Co…

Sui对外开放开发者Office Hour

Sui宣布开启新一轮的Sui开发工程师Office Hour。本期的Office Hour由Sui基金会和Mysten Labs共同主办&#xff0c;为Sui上开发的相关技术问题进行答疑解惑并提供支持。 开发工程Office Hour将于每周五1:00 AM&#xff08;GMT8&#xff09;开设&#xff0c;时长为1小时。 每个…

程序性能优化实践总结——JAVA

文章目录 1、 衡量程序性能的指标2、Java 程序性能优化切入点3、获取程序的性能数据1、nmon:获取系统性能数据2、jvisualvm:获取JVM性能数据3、jmc:获取Java应用详细性能数据4、arthas:获取单个请求的调用链耗时5、wrk获取Web接口的性能数据 4、应用程序优化1、缓冲区2、缓存3、…

vm.min_free_kbytes调整导致GI异常,kernel: oracle: page allocation failure

有个11204 rac的测试环境&#xff0c;客户反馈凌晨rman全备时偶尔会有内存耗尽导致数据库重启的情况&#xff0c;不是合同内的维护环境&#xff0c;请我们帮忙处理。我估计是没配置vm.min_free_kbytes&#xff0c;之前也调整多次每次都成功完成&#xff0c;就没有多想&#xff…

ROS1 图像数据转发

为节约带宽提高效率采用jpeg: sensor_msgs::CompressedImage image_msg; ros::Publisher img_pub n.advertise<sensor_msgs::CompressedImage>(“image1”, 10); image_msg.format“jpeg” ; image_msg.data.resize(jpeg_data_size); memcpy(image_msg.data.data(),jpeg…

【CUDA编程】 动态体素化实现

动态体素化实现 动态体素化DV克服了硬体素化HV的一些缺点。动态体素化DV保留了分组grouping阶段&#xff0c;相反&#xff0c;它没有采样固定的点数或体素容量&#xff0c;它保留了点和体素之间的完全映射。因此&#xff0c;体素数和每个体素中的点数都是动态的&#xff0c;依…

深入理解 SpringBoot 日志框架:从入门到高级应用——(七)SpringBoot日志配置

SpringBoot 官方文档&#xff1a;https://docs.spring.io/spring-boot/docs/2.7.12/reference/htmlsingle SpringBoot 底层依赖 Spring Boot 对所有内部日志记录使用 Commons Logging&#xff0c;但使底层日志实现保持为打开状态。 为 Java Util Logging、Log4J2 和 Logback …

【计算机网络自顶向下】如何学好计网-第一章概论

相关术语 URI&#xff1a;Uniform Resource Identifier 统一资源标识符&#xff0c;指的是一个资源 URL&#xff1a;Uniform Resource Location 统一资源定位符&#xff0c;URI的子集&#xff0c;用地址定为的方式指定一个资源 URN&#xff1a;Uniform Resource Name 统一资…

DBeaver连接SQLite数据库

一、前言 SQLite小巧轻便的开源免费关系型数据库&#xff0c;适合嵌入单机应用随身携带。桌面版推荐使用DBeaver。 官网&#xff1a;SQLite Download Page github&#xff1a;GitHub - sqlite/sqlite: Official Git mirror of the SQLite source tree 类似的开源免费且小巧…

vue+elementui实现app布局小米商城,样式美观大方

目录 一、效果图 1.首页效果图 2.分类 3.购物车 4.我的 5.登录注册 6.商品详情 7.搜索 二、项目实现 1.项目结构、设计说明 2.路由配置实现 3.首页实现源码 4.登录注册实现&#xff0c;模拟登录注册流程&#xff0c;用户数据存储到本地浏览器缓存 三、总结 一、效果…

『2023北京智源大会』开幕式以及基础模型前沿技术论坛

『2023北京智源大会』开幕式以及基础模型前沿技术论坛 文章目录 一. 黄铁军丨智源研究院院长1. 大语言模型2. 大语言模型评测体系FlagEval3. 大语言模型生态(软硬件)4. 三大路线通向 AGI(另外2条路径) 二. Towards Machines that can Learn, Reason, and Plan(杨立昆丨图灵奖得…

UE4/5样条线学习(四):样条线的创建和自然摆动

这一次我们创建一个actor蓝图&#xff0c;不过我们这次并不需要在一开始就创建样条线组件&#xff0c;而是在游戏中根据两个点去创建样条线&#xff0c;然后用时间轴根据样条线带动物品旋转位移。 制作&#xff1a; 组件部分&#xff1a; 第一步&#xff0c;创建一个actor蓝图…

CSDN铁粉增长秘籍

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…

【Jmeter】在进行综合场景压测时,由于不同的请求,要求所占比例不同,那如何实现呢?

在进行综合场景压测时&#xff0c;由于不同的请求&#xff0c;要求所占比例不同&#xff0c;那如何实现呢&#xff1f; 有人说将这些请求分别放到单独的线程组下&#xff0c;然后将线程组的线程数按照比例进行配置&#xff0c;这种方法不是很好&#xff0c;想想&#xff0c;不…

【计算机网络自顶向下】如何学好计网-第二章应用层

第二章 应用层 应用层协议原理 网络应用程序体系结构 客户机/服务器体系结构&#xff1a;至少有一个服务器&#xff0c;一个客户机&#xff0c;其中服务器总是打开的&#xff0c;具有固定的众所周知的IP地址&#xff0c;主机群集常被用于创建强大的虚拟服务器&#xff0c;而客…

OpenCV 笔记_1

笔记_1 文章目录 笔记_1Mat类数据类型读取Mat类支持的运算图像读取&#xff0c;显示&#xff0c;保存imread 图像读取namedWindow 创建要显示的窗口imshow 窗口显示imwrite 图像保存 视频加载与摄像头的使用VideoCapture 加载视频或摄像头get 获取属性VideoWriter 保存视频 图像…

vue 生命周期

人的-生命周期 一组件从 创建 到 销毁 的整个过程就是生命周期 Vue_生命周期 1. 钩子函数 Vue 框架内置函数&#xff0c;随着组件的生命周期阶段&#xff0c;自动执行 作用: 特定的时间点&#xff0c;执行特定的操作 场景: 组件创建完毕后&#xff0c;可以在created 生命周期…

实际项目中使用gorm-gen来生成实体类

一、为什么要使用gorm-gen来生成实体类和查询 1、根据gorm官网地址&#xff0c;正常的写法是先写数据模型,然后由数据模型自动同步生成到数据库中,但是这样的工作量会比较大,对于写后端的人来说都熟悉sql语句,正常来说都是先自己手动创建表,利用工具将表字段同步到项目实体类中…

java商业销售分析系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 商业销售分析系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…