本文介绍: 是一个类,包含权限管理功能,其中Mixin(混入)代表这个类不能单独作为ModelAdmin使用需要与其他的ModelAdmin类共同作为子类父类,新的子类即可既有ModelAdmin功能也有Guardian权限管理功能。用超级管理员账户,打开某位教师的信息详情页,在右上角出现的“对象权限按钮,就是我们配置guardian插件体现的效果用户身份写入管理员名字点击管理用户,便可设置管理员针对对象权限设置,共有增删改查四种设置。三个属性设为True,在管理界面的。

内置权限管理

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

图形界面配置权限

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

python manage.py createsuperuser

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

Image

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

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

Image

代码创建用户并配置权限

代码可以自动批量创建用户。可以djangoshell, 也可写入文件。 以djangoshell为例, 先在项目目录运行djangoshellpython 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一般写为以addchangedeleteview开头,后接下划线表名小写,例如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最直观的特色就是在djangoadmin页面可以图形化使用对象权限功能。 首先,在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

原文地址:https://blog.csdn.net/ldq_sd/article/details/131249269

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24672.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注