zoukankan      html  css  js  c++  java
  • 万能权限管理组件(仅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

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

    渐变 --> 突变
  • 相关阅读:
    HDU4611+数学
    HDU4612+Tarjan缩点+BFS求树的直径
    HDU4602+推导公式
    HDU4607+BFS
    HDU1353+贪心
    HDU4545+LCS
    HDU4548+素数
    HDU4539+状态压缩DP
    HDU2110+母函数
    HDU1569+最大点权集
  • 原文地址:https://www.cnblogs.com/lybpy/p/8537128.html
Copyright © 2011-2022 走看看