目录

    1. Django内置权限管理

    1.1 权限分类

    1. Permission 用来定义用户User A对任务Task的权限。
    2. User 如果User A 对Model B有权限,那么User A 对Mode B中的全部实例都有相应权限。User对象的user_permission字段用于管理用户的权限。使用assign_perm给User分配权限。
    3. Group 如果Group C 对Model B有权限,那么属于Group C的全部User对Model B 都具有相应权限。

    1.2 配置和实现

    1. Permission

    Django定义每个model后,默认都会添加该model的add, change和delete三个permission,自定义的permission可以在定义model时手动添加:

    class Task(models.Model):
        ...
        class Meta:
            permissions = (
                ("view_task", "Can see available tasks"),
                ("change_task_status", "Can change the status of tasks"),
                ("close_task", "Can remove a task by setting its status as closed"),
            )
    

    每个permission都是django.contrib.auth.Permission类型的实例,该类型包含三个字段name, codename 和 content_type,其中 content_type反映了permission属于哪个model,codename如上面的view_task,代码逻辑中检查权限时要用, name是permission的描述,将permission打印到屏幕或页面时默认显示的就是name。

    在model中创建自定义权限,从系统开发的角度,可理解为创建系统的内置权限,如果需求中涉及到用户使用系统时创建自定义权限,则要通过下面方法:

    from myapp.models import Post
    from django.contrib.auth.models import Permission
    from django.contrib.contenttypes.models import ContentType
    
    content_type = ContentType.objects.get_for_model(Post)
    permission = Permission.objects.create(codename='can_publish', name='Can Publish Posts', content_type=content_type)
    
    1. User和Group

    django的内置权限认证被绑定在 django.contrib.auth中,而auth中的Permission模型又依赖于contenttypes。

    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
    )
    
    manage.py syncdb
    

    就会在数据库中,建立如下几个表:

    • auth_group
    • auth_group_permissions
    • auth_permission
    • auth_user
    • auth_user_groups
    • auth_user_user_permissions

    从表名上可以看到,auth_user有两个外部对应关系,groups和user_permissions。

    manage.py  shell
    

    上面的命令,能够让解释器加载Django项目中的settings文件,进入可以对项目中对象直接操作的模式。

    >>> from django.contrib.auth.models import User
    >>> A  = User.objects.create_user('name','nameg@email.com','password')
    >>> A.groups = [group_list]
    >>> A.user_permissions = [permission_list]
    

    每个对象的groups和user_permissions都有三个用于修改权限的方法。 A.groups.[add|remove|clear()] A.user_permissions.[add|remove|clear()]

    1.3 使用

    通常使用有两种方法,

    • 在View函数中通过调用has_perm()函数来检测。 A/Group.has_perm(‘applabel.task’) 用于检查用户/组的权限。另外,A.get_all_permissions()列出用户的所有权限,A.get_group_permissions()列出用户所属组的权限。
    • 在View函数前使用装饰器。 @permission_required(‘applabel.task’)

    2. Django-guardian

    以通常的多人博客系统为例,每篇博文就是一个对象。上述的Django内置权限控制方式,达不到对象级的控制能力。Django中没有提供对象级别的权限控制,但是在架构上留下了接口。django-guardian就是一个很流行的对象级权限控制组件。Object Permission是一种对象颗粒度上的权限机制,它允许为每个具体对象授权。如果把对象b的读写权限赋予User A ,那么User A只具有对对象b的读写权限,而不能对其他同类对象进行操作。

    2.1 配置

    
    pip install django-guardian
    
    INSTALLED_APPS = (
        'guardian',
    )
    
    AUTHENTICATION_BACKENDS = [
        'django.contrib.auth.backends.ModelBackend', # this is default
        'guardian.backends.ObjectPermissionBackend',
    ]
    #如果要支持匿名用户AnoymousUser的Object级别的权限控制,要在settings中加入
    #匿名用户权限控制
    ANONYMOUS_USER_ID = -1
    
    python manage syncdb
    

    就会在数据库中,建立如下几个表:

    • guardian_groupobjectpermission
    • guardian_userobjectpermission

    2.2 使用

    1. 权限的编辑 guardian.shortcuts.assign(perm, user_or_group, obj=None) 添加权限 guardian.shortcuts.remove_perm(perm,user_or_group=None, obj=None) 删除权限 guardian.shortcuts.get_perms(user_or_group,obj) 获取全部权限

      • perm,这个参数是一个字符串,代表一个许可,格式必须为app.perm_codename或者perm_codename。但是如果第三个参数是None,则必须为app.perm_codename格式。因此建议还是统一使用app.perm_codename格式。注意app并不是app的全路径,而是最后一级的模块名。这一点和INSTALL_APP中的app全路径不同,如果你的app module不只一级的话,这地方一定要注意。
      • user_or_group,这个参数是一个User或者Group类型的对象。
      • obj,这个参数就是相关的对象了。改参数是可省略的,如果省略则赋予Model权限。
    2. 权限的检测

      • user.has_perm(‘app.view_task’)#检测权限
      • ObjectPermissionChecker(request.user).has_perm(‘app.view_task’, task)
      • guardian.decorators.permission_required()

    3. 参考资料