• django的自定义权限


    最近在写发布系统,涉及到权限的控制

    参考 黄小墨同学的博客实现了

    如下  

    1;定义一张权限控制的表

     1 [root@localhost app01]# tailf -25 models.py
     2 
     3 
     4 
     5 class Permission(models.Model):
     6     name = models.CharField("权限名称", max_length=64)
     7     url = models.CharField('URL名称', max_length=255)
     8     chioces = ((1, 'GET'), (2, 'POST'))
     9     per_method = models.SmallIntegerField('请求方法', choices=chioces, default=1)
    10     argument_list = models.CharField('参数列表', max_length=255, help_text='多个参数之间用英文半角逗号隔开', blank=True, null=True)
    11     describe = models.CharField('描述', max_length=255)
    12 
    13     def __str__(self):
    14         return self.name
    15 
    16     class Meta:
    17         verbose_name = '权限表'
    18         verbose_name_plural = verbose_name
    19         #权限信息,这里定义的权限的名字,后面是描述信息,描述信息是在django admin中显示权限用的
    20         permissions = (
    21             ('views_svns_list', '查看svn版本库信息表'),
    22             ('views_onlinecode_info', '查看推送代码详细信息表'),
    23             ('views_assets_info', '查看资产详细信息表'),
    24         )

    2:定义权限文件

    [root@localhost app01]# cat permission.py
    #!/usr/bin/env python
    #_*_coding:utf-8_*_
    from django.shortcuts import render
    from app01 import models
    from django.db.models import Q
    from django.core.urlresolvers import resolve   #此方法可以将url地址转换成url的name
    
    def perm_check(request, *args, **kwargs):
        url_obj = resolve(request.path_info)
        url_name = url_obj.url_name
        perm_name = ''
        #权限必须和urlname配合使得
        if url_name:
            #获取请求方法,和请求参数
            url_method, url_args = request.method, request.GET
            url_args_list = []
            #将各个参数的值用逗号隔开组成字符串,因为数据库中是这样存的
            for i in url_args:
                url_args_list.append(str(url_args[i]))
            url_args_list = ','.join(url_args_list)
            #操作数据库
            get_perm = models.Permission.objects.filter(Q(url=url_name) and Q(per_method=url_method) and Q(argument_list=url_args_list))
            if get_perm:
                for i in get_perm:
                    perm_name = i.name
                    perm_str = 'app01.%s' % perm_name
                    if request.user.has_perm(perm_str):
                        print('====》权限已匹配')
                        return True
                else:
                    print('---->权限没有匹配')
                    return False
            else:
                return False
        else:
            return False   #没有权限设置,默认不放过
    
    
    def check_permission(fun):    #定义一个装饰器,在views中应用
        def wapper(request, *args, **kwargs):
            if perm_check(request, *args, **kwargs):  #调用上面的权限验证方法
                return fun(request, *args, **kwargs)
            return render(request, '403.html', locals())
        return wapper

    3:定义views.py

    from app01.permission import  check_permission
    
    @login_required(login_url='/login/')
    @check_permission
    def svnupdate(request,svn_id,u_type):
        pass

    20170426
    添加权限控制,具体使用方式登录admin,然后在权限表里操作。
    权限名称 就是models中定义的权限
    URL名称 就是具体访问的某个url 就是在urls.py里的name字段
    以上两个字段必须和models中和url中的一致。
    添加这个为拒绝的权限,如果普通用户需要访问,需要单独对普通用户授权。
    点击admin 的User选项,具体的赋权操作

    以上权限控制对应的是单个页面的,根据自己业务的不同,发布系统需要按项目实现对用户的控制,比如:A项目user1有发布的权限。B项目user2 有发布的权限,user3 有AB两个项目的所有权限。这样上面的权限管理就无法满足需求。于是参照上面的例子,自己改了改。大致的方式就是 加一个表存储 用户和发布项目的对应关系,然后在比较request.user.username和数据库里的这个表,如果存在,就返回True,然后获取项目id,比较这个用户在数据库里的的项目是否存在。

    代码为:

    models.py  并没有用多对多的关系,当时选择多对多的关系好多问题,于是干脆搞成这样了

     1 class svn_permission(models.Model):
     2     permission_info = models.CharField(max_length=100,blank=True,null=True)
     3     web_users = models.CharField(max_length=100)
     4     svn_projects = models.TextField()
     5 
     6     def __unicode__(self):
     7         return self.permission_info
     8     class Meta:
     9         verbose_name = 'SVN权限表'
    10         verbose_name_plural = verbose_name
    11 
    12 
    13 class online_permission(models.Model):
    14     permission_info = models.CharField(max_length=100,blank=True,null=True)
    15     web_users = models.CharField(max_length=100)
    16     src_dir = models.TextField()
    17 
    18     def __unicode__(self):
    19         return self.permission_info
    20     class Meta:
    21         verbose_name = '上线代码权限表'
    22         verbose_name_plural = verbose_name

    权限py文件

    cat svnprojectpermission.py  

    #!/usr/bin/env python
    #_*_ coding:utf-8_*_
    
    from django.shortcuts import render
    from app01 import models
    from django.db.models import Q
    from django.core.urlresolvers import resolve
    
    def perm_svnproject_check(request,**kwargs):
        url_obj = resolve(request.path_info)
        print("urlobj",url_obj)
        print"webusername",request.user.username
        url_name = url_obj.url_name
        print "---->urlname:",url_name
        kw = url_obj.kwargs
        print("kwargs",kw)
    
        for k,v in kw.items():
            if k=='svn_id':
                print'v',v
                adf = str(models.svns.objects.get(id=v))
                print("web submit svnproject",adf)
                all_list = []
                sql_infos = models.svn_permission.objects.all()
                for info in sql_infos:
                    users = info.web_users
                    all_list.append(users)
                    svn_pro = str(info.svn_projects).split(',')
                    all_list.append(svn_pro)
                    print("user,svn_pro",users,svn_pro)
                print("all_list",all_list)
                webuser = str(request.user.username)
                if webuser in all_list:
                    num = all_list.index(webuser)
                    print"user success"
                    print("num",num)
                    webdir = str(adf)
                    if adf in all_list[num+1]:
                        print("--success--")
                        return True
                    else:
                        print("fail")
                        return False
                else:
                    print("---no include user---fail--- ")
                    return False
    
    def check_svnproject_permission(fun):
        def wapper(request, *args, **kwargs):
            if perm_svnproject_check(request, **kwargs):
                return fun(request, *args, **kwargs)
            return render(request, 'forbiden.html', locals())
        return wapper

    具体的方式参考发布系统里的代码  

  • 相关阅读:
    Window.ActiveXObject的用法 以及如何判断浏览器的类型
    PDO预处理
    *p=&a是把a的值赋给p,p=&a是把a的地址赋给p。
    牛客网
    关于stable_sort()和sort()的区别
    求最小公倍数
    成绩排序
    二叉树的存储、创建以及遍历
    关于sort函数的几种用法
    vector的用法
  • 原文地址:https://www.cnblogs.com/dribs/p/6767914.html
Copyright © 2020-2023  润新知