万能权限管理组件(仅django)

#permissions.py

from
django.core.urlresolvers import resolve  #将url反解为url_name from django.shortcuts import render,redirect from django.conf import settings class CP(object): def __init__(self,perm_dict={}):  #默认没有任何权限 self.perm_dict = perm_dict def check_permssion(self,func):  #该装饰视图逻辑,检查权限 def inner(*args, **kwargs): if self.perm_check(*args, **kwargs): return func(*args, **kwargs) return render(args[0], '403页面.htm')  #403自己定制 return inner def perm_check(self,*args, **kwargs):    #干活的方法 request = args[0] # request if request.user.is_authenticated(): # 用户未认证先登录 if request.user.is_superuser: return True current_url_name = resolve(request.path_info).url_name # 当前访问的url的name值 status = False for k, v in self.perm_dict.items(): # 循环权限字典 if request.user.has_perm('%s.%s' % (k.split('_')[0], k)): if current_url_name == v[0]: # 判断当前name是否在权限中 if request.method == v[1]: # 判断用户在该视图中的请求方法 data_for_method = getattr(request, v[1]) args_status = True for item in v[2]: if not data_for_method.get(item): args_status = False break if args_status: kwargs_status = True for v_name, v_value in v[3].items(): if data_for_method.get(v_name) != str(v_value): kwargs_status = False break if kwargs_status: if len(v) == 5: return True if v[4](request) else False    #传入request,调用定制函数 return True return status return redirect(settings.LOGIN_URL)    #重定向可自己决定 permssion = CP()

两个不通用的地方:403页面 和 重定向

流程:

1、逻辑代码如上,使用单例模式;通过装饰器检查访问视图函数的权限

2、用户自定义权限字典

from permissions import permission

def check(request):  #定制过滤函数

  pass

perm_dict = {

  权限名:[ url_name,请求method,[ 过滤内容名 ],{ 过滤具体内容 },可选的定制函数名 ],

  ...

 }

permssion.perm_dict=perm_dict

  • 权限名(字符串):应用名_会意命名,下划线后用url_name即可;注意应用名的选取
  • url_name(字符串):url后的name值
  • 方法(字符串):GET或POST
  • [ 过滤内容名 ]:前端GET提交的内容,url中输入的,或其它。url中?后内容
  • { 过滤具体内容 }:键值对形式精确过滤
  • 可选的定制函数名:可选,只写函数名,必须传入一个位置参数,该参数当作请求的request使用,最终返回True或False

权限规则:

  • perm_dict 不定制,则没有任何权限,除非是超级用户
  • 权限列表中前两个若有空字符串,则没有该权限;后三个若有空则表示通过

3、装饰视图类或视图函数

  • 类:参考django装饰器一节装饰器的用法
  • 函数:
from .permissions import permssion

@permssion.check_permssion
def index(request):
  pass

4、models.py中的UserProfile类(取代django默认的auth.user)

class UserProfile(AbstractBaseUser,PermissionsMixin):
    '''
     is_active和is_staff同时为True才能登录
    '''
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    name = models.CharField(verbose_name='姓名', max_length=64)
    role = models.ManyToManyField('Role', blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=True)

    objects = UserProfileManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):              # __unicode__ on Python 2
        return self.email

    class Meta:
        verbose_name = '用户信息表'
        verbose_name_plural = verbose_name

        #权限
        permissions = (
            ('crm_myadmin_index','myadmin的首页'),  
            ('crm_app_model_obj_change','表修改'),
            ('crm_app_model_obj_list','查看表记录列表'),
            ('crm_app_model_obj_change_save','表修改并保存')
        )

如上:权限元组中第一项即我们定义的权限名,第二项是说明

最后:makemigrations,migrate

现在,在后台就能赋予用户我们自定制的权限了。(删除权限名须在数据库中删除)

渐变 --> 突变
原文地址:https://www.cnblogs.com/lybpy/p/8537128.html