Django内置的用户权限

做Web的大部分都有一个后台用于管理一些数据的增删改查,而Django 内置了一个权限系统。它提供了为指定的用户和用户组分配权限的方法。它在 Django 管理后台界面里使用,但你也可以在自己的代码中使用它。(图网上找的,django内置的权限差不多就是这样的)

1、创建一个Django项目:

django-admin startproject 工程名称

2、创建子应用:

python manage.py startapp 子应用名称

创建完子应用需要注册的要不然模型类迁移不会成功

以下就在demo2中演示。

3、创建模型类:

在demo2中新建了一个models.py用于写模型类对象内容如下:

from django.contrib.auth.models import AbstractUser
from django.db import models


# Create your models here.

class User(AbstractUser):
    """用户模型类
    创建自定义的用户模型类
    Django认证系统中提供的用户模型类及方法很方便,我们可以使用这个模型类,但是字段有些无法满足项目需求,如本项目中需要保存用户的手机号,
    需要给模型类添加额外的字段。
    Django提供了django.contrib.auth.models.AbstractUser用户抽象模型类允许我们继承,扩展字段来使用Django认证系统的用户模型类。

    我们自定义的用户模型类还不能直接被Django的认证系统所识别,需要在配置文件中告知Django认证系统使用我们自定义的模型类。
    在配置文件中进行设置
    AUTH_USER_MODEL = 'users.User'
    AUTH_USER_MODEL 参数的设置以点.来分隔,表示应用名.模型类名。
    """
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name


# 定义图书模型类BookInfo
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20, wverbose_name='名称')
    bpub_date = models.DateField(verbose_name='发布日期')
    bread = models.IntegerField(default=0, verbose_name='阅读量')
    bcomment = models.IntegerField(default=0, verbose_name='评论量')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_books'  # 指明数据库表名
        verbose_name = '图书'  # 在admin站点中显示的名称
        verbose_name_plural = verbose_name  # 显示的复数名称```

    def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.btitle


# 定义英雄模型类HeroInfo
class HeroInfo(models.Model):
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    hname = models.CharField(max_length=20, verbose_name='名称')
    hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
    hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
    hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书')  # 外键
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_heros'
        verbose_name = '英雄'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.hname

我定义了三个模型类分别是User、BooInfo、HeroInfo

4、进行迁移

将模型类同步到数据库中。

1、生成迁移文件

python manage.py makemigrations

2、同步到数据库中

python manage.py migrate

5、数据库中自动生成的表

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

我例子中用的是默认的懒得写,下面就大概说说:

6、自定义权限

自定义权限(一)

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

如何取消默认权限?


class Blog(models.Model):
    .....
    
    class Meta:
        default_permissions = ()
 
        .......

default_permissions: 清空默认的权限

注意:如果你使用了django默认的admin的话,建议保留4个默认权限,可以添加新权限

class User(AbstractUser):

    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

     class Meta:
        permissions = (
            ('add_user_per', '添加用户权限'),
            ('del_user_per', '删除用户权限'),
            ('change_user_per', '修改用户权限'),
            ('sel_user_per', '查询用户权限')
        )
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

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

自定义权限(二)

在业务逻辑中创建权限,则可以通过Permission模型来创建权限

def add_user_permission(request):
    if request.method == 'GET':
        # 获取当前Users模型的id值
        content_type = ContentType.objects.get_for_model(User)
        # codename为权限名,name为描述,content_type为当前权限属于哪一个模型的ID
        Permission.objects.create(
            codename='add_other_user_permission',
            name='添加其他用户权限',
            content_type=content_type
        )
        return HttpResponse('创建权限成功')

7、分配权限

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

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

语法:

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

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

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

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

语法:

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

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

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

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

(3)分配用户和权限组

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

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

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

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

示例如下:

from django.views.generic import View
from demo2.models import User
from django.contrib.auth.models import Permission, Group
from django.http import HttpResponse


# 添加权限
class AddQx(View):
    def get(self, request):
        user_id = request.GET.get('user_id', 1)
        pres_list = request.GET.getlist('pres')
        pres_str = pres_list[0].split(',')

        user = User.objects.get(id=user_id)
        pres = Permission.objects.filter(codename__in=pres_str)
        print(pres)
        for pre in pres:

            user.user_permissions.add(pre)
        return HttpResponse('添加权限成功')


# 修改权限
class ChangeQx(View):
    def get(self, request):
        user_id = int(request.GET.get('user_id', '1'))
        pres_list = request.GET.getlist('pres')
        pres_str = pres_list[0].split(',')
        user = User.objects.get(id=user_id)
        # 修改权限先清空权限,在添加
        user.user_permissions.clear()
        user.user_permissions.add(pres_str)
        return HttpResponse('修改权限成功')


# 删除权限
class DeleteQx(View):
    def get(self, request):
        user_id = int(request.GET.get('user_id', '1'))
        pres_list = request.GET.getlist('pres')
        pres_str = pres_list[0].split(',')
        pres = Permission.objects.filter(codename__in=pres_str)
        user = User.objects.get(id=user_id)
        user.user_permissions.remove(pres)
        return HttpResponse('删除权限成功')


# 查看权限
class ViewQx(View):
    def get(self, request):
        user_id = int(request.GET.get('user_id', '1'))
        user = User.objects.get(id=user_id)
        all_per = user.get_all_permissions()
        if user.has_perms(['demo2.add_bookinfo']):
            print('用户具有添加书籍的权限')
        return HttpResponse(all_per)


# 创建组
class AddGroup(View):
    def get(self, requset):
        name = requset.GET.get('name', 'xxx')
        try:
            group = Group(
                name=name
            )
            group.save()
            return HttpResponse('创建组成功')
        except:
            return HttpResponse('创建组失败')


# 添加组权限
class AddGroupQx(View):
    def get(self, requset):
        ser_id = int(requset.GET.get('user_id', '1'))
        super_group = Group.objects.get(id=8)
        pers = Permission.objects.filter(codename__in=[
            'add_bookinfo',
            'change_bookinfo',
            'delete_bookinfo',
            'view_bookinfo'])
        for per in pers:
            # 添加超级用户组的权限
            super_group.permissions.add(per)
        #     # 删除超级组的权限
        #   super_group.permissions.remove(per)
        #     # 清空组的权限
        # super_group.permissions.clear()
        return HttpResponse('创建组权限')


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

8、检测权限

(1)使用has_perm方法:

语法:

用户对象.has_perm('应用名.权限codename')

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

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

class JaoYan(View):
    def get(self, request):

        # 获取id=1d的用户对象
        user = User.objects.get(id=1)
        # 查看用户的所有权限
        all_perm = user.get_all_permissions()
        # 查看用户的组权限
        group_perm = user.get_group_permissions()
        # 查询用户是否有add_user_per权限
        if user.has_perm('demo2.change_bookinfo'):
            return HttpResponse('用户有delete_bookinfo权限')
        else:
            return HttpResponse('用户没有delete_bookinfo权限')

user.has_perm('demo2.change_bookinfo')会返回布尔类型

(2)使用permission_required装饰器

语法:@permission_required('应用app名.权限名codename')

源代码:

def permission_required(perm, login_url=None, raise_exception=False):
    """
   视图的装饰器,用于检查用户是否已启用特定权限,并在必要时重定向到登录页面。如果给了 
   raise_exception参数,则会引发PermissionDenied异常
    """
    def check_perms(user):
        if isinstance(perm, str):
            perms = (perm,)
        else:
            perms = perm
        # First check if the user has the permission (even anon users)
        if user.has_perms(perms):
            return True
        # In case the 403 handler should be called raise the exception
        if raise_exception:
            raise PermissionDenied
        # As the last resort, show the login form
        return False
    return user_passes_test(check_perms, login_url=login_url)

permission_required有三个参数:

perm:描述权限的字符串,格式为:app名.权限。如"auth.add_user",“auth.delete_user”

login_url:如果没有权限需要跳转的url字符串,如"/login",“https://www.baidu.com”

raise_exception:boolean值,没有权限是否触发PermissionDenied异常,触发异常则直接返回,不会跳转到login_url

示例:

class UserGroup(View):
    @method_decorator(permission_required('demo2.view_bookinfo', raise_exception=True))
    def get(self, request):
        # 给id为1的用户分配超级管理员组的权限
        # 获取超级管理员组group对象
        super_group = Group.objects.get(name='xxx')
        # 获取id=1d的用户对象
        user = User.objects.get(id=1)
        # 添加超级用户组的权限
        user.groups.add(super_group)
        return HttpResponse('创建用户组权限')

 

Django权限最小的粒度是表,如果需要更小的粒度需要Django-guardian

pip install django-guardian

 

 

 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Django 提供了一个强大的权限系统,可以帮助你管理用户权限。在 Django 中,你可以使用内置的 User 和 Group 模型来管理用户和用户组。 首先,你需要在你的 Django 项目中启用权限系统。在你的 settings.py 文件中,确保 'django.contrib.auth' 和 'django.contrib.contenttypes' 应用被添加到了 INSTALLED_APPS 列表中。 接下来,你可以使用 Django 的认证系统来处理用户认证和授权的任务。你可以使用以下方法来检查用户权限: 1. `user.has_perm(permission, obj=None)` - 检查用户是否有指定的权限。`permission` 参数是一个字符串,表示权限的名称。`obj` 参数是可选的,用于在特定对象上检查权限。 2. `user.has_perms(permissions, obj=None)` - 检查用户是否拥有所有指定的权限。`permissions` 参数是一个字符串列表,表示多个权限的名称。 3. `user.has_module_perms(app_label)` - 检查用户是否对指定应用程序拥有任何权限。`app_label` 参数是应用程序的名称。 此外,你还可以使用装饰器 `@permission_required` 和 `@login_required` 来限制对视图函数的访问权限。`@permission_required` 装饰器可以确保只有具有特定权限的用户才能访问被装饰的视图函数,而 `@login_required` 装饰器可以确保只有已登录的用户才能访问被装饰的视图函数。 当然,你也可以自定义权限,通过在 models.py 中创建 Permission 对象,并在 User 或 Group 对象上分配这些自定义权限。 要了解更多关于 Django用户权限管理的信息,可以参考 Django 官方文档中的相关章节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值