zoukankan      html  css  js  c++  java
  • Django默认权限机制介绍及实践

    演示Django版本为当前最新版本v2.2

    当Django配置文件中的INSTALL_APPS包含了django.contrib.auth时,就默认启用了一个简单的权限系统,提供了为用户或组分配权限的方法

    之所以说简单呢?主要是因为:

    1. 默认的权限系统是基于表的控制,权限最小粒度是表

    也就是说,假如有一个Blog表,我们可以赋予用户或组对Blog表有delete的权限,那么用户或组成员就可以删除全部Blog,是不能控制用户只能删除自己创建的blog的

    如果希望用户只能删除自己创建的Blog,不能删除别人创建的Blog,这种需求Django默认的权限管理就无法实现了,需要用到object permission对象权限,有第三方模块实现了对象权限,如django-guardian,你可以直接使用,或者也可以自己实现对象权限,具体思路可参考这篇文章:Django内置权限扩展案例

    1. 每个Model模型默认只有四个权限,分别是添加add_、修改change_、删除delete_、查看view_,这些权限记录在Permission表中,表数据如下:

    默认权限的创建是通过Django的信号signals实现的,使用了post_migrate信号,在每次执行migrate操作时都会为新的Model模型创建默认权限,关于Django的信号Signals介绍和使用可以查看这篇文章:Django使用Signals监测model字段变化发送通知

    自定义权限

    默认的权限名字和描述都是英文的,且只有四个,如果你不想用默认的几个权限,想要自定义的话,可以这样做:

    class Blog(models.Model):
        title = models.CharField(max_length=256, verbose_name='标题')
        content = models.TextField(blank=True, null=True, verbose_name='内容')
        
        class Meta:
            default_permissions = ()
    
            permissions = (
                ("change_blog", "修改博客"),
                ("delete_blog", "查看博客"),
                ("publish_blog", "发布博客"),
            )
    

    default_permissions: 清空默认的权限

    permissions: 设置权限,内容是一个嵌套的列表,列表第一个字段是codename,第二个字段为name

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

    权限修改

    如果你用了Django自带的admin,在migrate之后就能在admin的user和group两个表中看到新添加的权限了

    当然你也可以在程序中来添加或修改权限

    用户权限修改方法:

    ops = User.objects.get(id=2)
    
    ops.user_permissions.add(25, 26)
    ops.user_permissions.set([26, 27])
    ops.user_permissions.remove(26, 27)
    ops.user_permissions.clear()
    

    组权限修改方法:

    coffee = Group.objects.get(id=1)
    
    coffee.permissions.add(25)
    coffee.permissions.set([26,27])
    coffee.permissions.remove(25)
    coffee.permissions.clear()
    

    其中add为添加,set为设置,remove为移除,clear为清空,addset的区别是add会在原有权限的基础上加新权限,而set会清空原有权限设置成新的权限,后边的参数25,26,27可以为Permission的ID或者是Permission对象,例如这样也是可以的:

    p = Permission.objects.get(id=25)
    coffee.permissions.add(p)
    

    给组赋予权限,组内的所有用户会自动的拥有该组的权限,例如用户ops-coffee隶属于组SRESRE组对Blog表有修改权限,那么即便是没有单独给Y37用户分配任何权限,他也会有对Blog表的修改权限

    权限查看

    get_all_permissions()列出用户的所有权限:

    >>> User.objects.get(username='ops-coffee').get_all_permissions()
    {'blog.publish_blog', 'blog.delete_blog', 'auth.add_group', 'blog.change_blog'}
    

    get_group_permissions()列出用户所属组的权限:

    >>> User.objects.get(username='ops-coffee').get_group_permissions()
    {'blog.publish_blog', 'blog.change_blog', 'blog.delete_blog'}
    

    权限校验

    用户对象可以通过has_perm方法来判断用户是否拥有某个权限:

    >>> User.objects.get(username='ops-coffee').has_perm('blog.change_blog')
    True
    >>> User.objects.get(username='ops-coffee').has_perm('blog.delete_blog')
    True
    

    has_perm 的参数由<app label>.<permission codename>两部分组成,例如blog.delete_blog表示的就是名字为blog的APP下的delete_blog权限

    后端View校验权限

    可以直接在view中通过if判断用户权限,例如:

    def ops_coffee_view(request):
        if not request.user.has_perm('blog.change_blog')
            return HttpResponse('403 Forbidden')
    

    为了方便,Django还提供了一个permission_required()的装饰器,可以快速的来校验用户是否拥有特定的权限,用法如下:

    @permission_required(perm, login_url=None, raise_exception=False)
    

    三个参数的意思分别是:

    perm: 必须有,权限名称,同has_perm一样

    login_url: 非必须,登陆的url地址,当你没有权限时自动跳转到登陆页,这里可以设置登陆地址的url

    reise_exception: 非必须,当为True时,如果用户没有权限,则不会跳转到登陆页,而是引发PermissionDenied错误,返回403 Forbidden

    如下例子,判断用户是否有blog的APP的change_blog权限,如果没有则返回403错误

    @permission_required('blog.change_blog', raise_exception=True)
    def ops_coffee_view(request):
        ...
    

    前端Template中校验权限

    当前登陆用户的权限保存在模版变量{{ perms }}中,可以在模版中通过if判断用户是否拥有相应的权限而开放对应的内容,例如对于侧边栏菜单只显示用户有权限访问的,就可以这么写:

    {% if perms.cmdb.view_project %}
        <li><a href="{% url 'project-list-url' %}"></i> 项目列表</a></li>
    {% endif %}
    
    {% if perms.cmdb.view_service %}
        <li><a href="{% url 'service-list-url' %}"></i> 服务列表</a></li>
    {% endif %}
    
    {% if perms.cmdb.view_environment %}
        <li><a href="{% url 'environment-list-url' %}"></i> 环境列表</a></li>
    {% endif %}
    

    至此,Django的默认权限系统介绍完成,默认权限在小型项目中能满足大部分的需求,如果对权限控制有更高的要求可以关注前文中介绍的django-guardian项目或自己实现


    扫码关注公众号查看更多实用文章

    相关文章推荐阅读:

  • 相关阅读:
    Linux文件属性
    [Oracle] Listener的动态注册
    jQuery easyUI Pagination控件自定义div分页(不用datagrid)
    桂林电子科技大学出校流量控制器Android版1.0.0
    php使用check box
    Python windows ping
    Python selenium chrome 环境配置
    Linux wget auto login and backup database
    PyQt4 ShowHMDB show sqlite3 with QTableWidget summary
    PyQt4 py2exe 打包 HardwareManager
  • 原文地址:https://www.cnblogs.com/37Y37/p/11658651.html
Copyright © 2011-2022 走看看