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

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

原文地址:https://www.cnblogs.com/dribs/p/6767914.html