权限管理系统---django版本
权限管理:在简单的系统中,以往都是将每个权限赋予给用户,每个用户访问某个功能,通过查询db来判断用户是否有权限。但是如下情景不能够解决:
1、随着系统的复杂,权限较为复杂的时候,权限条目也多,系统角色较多的时候,我们不能重复的给每个角色赋予相同的权限,这里提出了权限虚拟角色的概念。
2、每个用户访问的UI界面应该是不同,而不是显示所有功能,这样用户体验能好些。也就说根据用户的权限来实现动态菜单显示。
大体设计思想如下:
- 我们自定义一些虚拟角色,这些虚拟角色包含一些权限,然后将虚拟角色赋予给用户,每次修改权限的时候,直接修改权限虚拟角色即可。
- 将权限细分为每个url,通过分配不同的url给权限虚拟角色即是功能上实现控制不同用户访问不同的UI界面,这样控制用户,不同的用户访问系统的时候,页面不一样,达到权限的控制。
url分类:
url大体分2类:
- 功能url:主要作用是实现系统的功能相关、和左边菜单无关。
- 菜单功能:右边菜单功能url,分两种:一种顶级菜单:这种菜单没有url跳转。一种是:次级菜单:有相应a标签的跳转url。
基于上面的总结,系统的权限表至少要包含:
- 实现功能url:表中需要有判断该url是功能url还是菜单url,比如:is_menu字段,由布尔值组成。true为菜单,false为功能url。
- 实现功能url:表中需要有有一个判断字段是否为本表中的id做为父id,字段定义为:parent_id,字段为None且is_menu值为True表示为顶级标签。不为None为次级标签,功能url为None。也就是说parent_id 可以是本表的id做foreign key 外键操作,也可以定义可为null的字段。
同时顶级标签url为空。即表中url字段为空。
表结构设计:
slqalchemy 表结构创建:(relationship方法内的不是表名而是类名,这种关系是建立在类和对象的基础而不是数据库上。)
1 from sqlalchemy.ext.declarative import declarative_base 2 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index,Boolean#导入列数据类型字段。 3 from sqlalchemy.orm import sessionmaker, relationship#导入会话函数、 4 from sqlalchemy import create_engine 5 engine = create_engine("mysql+pymysql://root:@192.168.31.222:3306/orm_test", max_overflow=15)#创建数据库引擎,通过连接池获取数据库的连接。数据库连接池数量为:15,默认值是5. 6 #创建sqlorm基类。(为声明的类定义基类。) 7 Base = declarative_base() 8 9 10 class Permisson(Base): 11 ''' 12 功能:该类是权限表结构。 13 ''' 14 __tablename__='permisson' 15 id=Column(Integer,autoincrement=True,primary_key=True) 16 caption=Column(String(48)) 17 parent_id=Column(Integer,ForeignKey('permisson.id'),nullable=True) 18 par_re=relationship('Permisson',backref='p') 19 is_menu=Column(Boolean) 20 url=Column(String(100),nullable=True) 21 data_method=Column(String(32)) 22 keywargs=Column(String(48)) 23 24 class Userinfo(Base): 25 ''' 26 功能:该表是用户表结构 27 ''' 28 __tablename__='userinfo' 29 id=Column(Integer,autoincrement=True,primary_key=True) 30 username=Column(String(36)) 31 password=Column(String(36)) 32 33 class Role(Base): 34 ''' 35 功能:该表是权限虚拟角色表结构。 36 ''' 37 __tablename__='role' 38 id=Column(Integer, autoincrement=True,primary_key=True) 39 rolename=Column(String(32)) 40 41 class UserinfotoRole(Base): 42 ''' 43 功能:该表是用户和权限虚拟角色多对多第三张表。 44 ''' 45 __tablename__='userinfotorole' 46 id=Column(Integer,autoincrement=True,primary_key=True) 47 user_id=Column(Integer,ForeignKey('role.id')) 48 role_id=Column(Integer,ForeignKey('userinfo.id')) 49 user_ob=relationship('UserinfotoRole',backref='ur') 50 role_ob=relationship('Role',backref='ur') 51 52 class RoletoPermisson(Base): 53 ''' 54 功能:该表是权限角色和权限的多对多的表结构。 55 ''' 56 __tablename__='roletopermisson' 57 id=Column(Integer,autoincrement=True,primary_key=True) 58 roleid=Column(Integer,ForeignKey('role.id')) 59 permissonid=Column(Integer,ForeignKey('permisson.id')) 60 pe_ob=relationship('Permisson',backref='rp') 61 ro_ob=relationship('Role',backref='rop') 62 63 Base.metadata.drop_all(engine)##执行该函数,他就会执行所有Base所有的子类。调用我们定义类并创建相应的表结构。
django版本的表结构:默认使用的数据库为sqlite。
1 from django.db import models 2 3 # Create your models here. 4 5 6 class Permission(models.Model): 7 caption=models.CharField(max_length=32) 8 is_menu=models.BooleanField() 9 parent_id=models.ForeignKey('Permission',related_name='nid',null=True,to_field='id') 10 url=models.CharField(max_length=32,null=True) 11 data_mothod=models.CharField(max_length=32) 12 keywargs=models.CharField(max_length=32) 13 14 15 class Userinfo(models.Model): 16 usename=models.CharField(max_length=32) 17 password=models.CharField(max_length=32) 18 19 20 class Role(models.Model): 21 rolename=models.CharField(max_length=32) 22 23 class Userinfotorole(models.Model): 24 user=models.ForeignKey('Userinfo') 25 role=models.ForeignKey('Role') 26 27 class PermissontoRole(models.Model): 28 permisson=models.ForeignKey('Permission',related_name='p',to_field='id') 29 role=models.ForeignKey('Role')
对permission表的解析:
django表:
默认情况下,django在数据库中给我们创建一个自增id列且为主键,所以我们不用想sqlalchemy那样手动创建主键。在django中创建foreign或者ManyToMany的时候,自动和父表的id主键列建立外键关系。
1 class Permission(models.Model): 2 caption=models.CharField(max_length=32) 3 is_menu=models.BooleanField() 4 parent_id=models.ForeignKey('Permission',related_name='nid',null=True,to_field='id') 5 url=models.CharField(max_length=32,null=True) 6 data_mothod=models.CharField(max_length=32) 7 keywargs=models.CharField(max_length=32)
字段解析:
- caption:列表表示菜单上文字。
- is_menu:判断当前行对象是否为菜单还是内容的url。字段属性是布尔。
- parent_id:该字段是关联自己表,建立的外键。也可以不建立外键关系。只要保证该值可以为空(必须可以为空,因为有可能该列的不属于菜单)。其中relate_name当我们进行反向查询的时候,查询的关联字段。避免和PermissontoRole表冲突。to_field='id'和哪个列关联。
- url:菜单和用户访问的url,该字段也必须可以为空,顶级的菜单只是文字并没有跳转,需要跳转的是次级菜单或者内容url。
- data_mothd:该字段使用或者请求这个权限或者url的方法。比如:POST、GET方法。因为在这个系统我们设计的是:权限对应url。
- keywargs:这个字段很重要;以为我们django给咱们提供的方法就2个:POST和GET请求。如果你给别人API的时候,如何提供:增、删、改、查?
查可以用:GET,增加可以用:POST,删除和改呢?
这个时候这个字段重要性就提现出来。我们可以在这个字段定义:add 、del、update、check。前端的进行请求的时候,无论是get还是POST:
1 $.ajax( 2 { 3 url:'/data/', 4 method:'POST', 5 data: {'type':'del','data':[1,23,4,5]}, 6 datatype:JSON, 7 success:function(data){ 8 void 0 9 } 10 } 11 )
后者GET请求:
1 import requests 2 3 playload={'user':'tome','type':'check'} 4 get_url='http://127.0.0.1:8888/data/' 5 f=requests.get(url=get_url,data=playload)#data参数只能是字典。 6 request_content=f.text 7 print(request_content)
后台可以根据前端发送的数据,取得"type"字段,然后可以根据类型 后台建立一个反射(attr),映射到不同的方法进行处理。
学习是一种态度,坚持是质变的利器!

浙公网安备 33010602011771号