python学习之基本权限管理系统
通过mysql和python相关知识实现简单权限管理系统。主要功能有添加、删除用户、添加删除权限以及分配权限等。实现过程中主要运用了mysql创建表、sql语句、外键、navicat使用、python模块pymysql操作mysql、python动态导入模块等相关知识。
一、数据库表设计
1、表的相关描述
表的具体信息描述

一共设计了4张表
用户信息表(user_type):存储用户名、密码信息,user_type_id为外键和角色表相关联‘,用来标识用户的角色
角色信息表(user_type):用来定义角色,如:普通用户,超级用户等
权限信息表(permission):用来定义权限信息,func是指实现该权限的方法,module是指该方法对应模块的路径,在python中可以动态导入该模块调用相关方法
权限和角色对应关系表(user_type_to_permission):user_type_id为外键是角色id和角色信息表关系,permission_id为外键是权限id和权限信息表关联
二、创建表
1、按照如下顺序创建表
角色表

CREATE TABLE user_type ( nid INT NOT NULL auto_increment PRIMARY KEY, NAME VARCHAR (30) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
用户信息表

CREATE TABLE user_info ( nid INT NOT NULL auto_increment PRIMARY KEY, username VARCHAR (30), passwd VARCHAR (30), user_type_id INT, FOREIGN KEY (user_type_id) REFERENCES user_type (nid) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
权限信息表

CREATE TABLE permission ( nid INT NOT NULL auto_increment PRIMARY KEY, caption VARCHAR (30), module VARCHAR (30), func VARCHAR (30) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
权限和角色对应关系表

CREATE TABLE user_type_to_permission (
nid INT NOT NULL auto_increment PRIMARY KEY,
user_type_id INT,
permission_id INT,
FOREIGN KEY (user_type_id) REFERENCES user_type (nid),
FOREIGN KEY (permission_id) REFERENCES permission (nid)
) ENGINE = INNODB DEFAULT CHARSET = utf8;
2、插入模拟数据

insert into user_type (name) values ('超级管理员'),('普通管理员'); insert into permission (caption,module,func) values ('添加用户','src.auth.user','add_user'),('删除用户','src.auth.user','del_user'); insert into user_info (username,passwd,user_type_id) values ('root','123',1),('yqh','123','2'); insert user_type_to_permission (user_type_id,permission_id) values (1,1),(1,2),(2,1);
三、程序实现
编写代码时主要遵从以下规则:1、为操作每一张表的sql专门写一个类 2、需要做连接查询时sql语句放在from后面那张表对应的类中 3、操作sql的代码和业务的代码分开在不同目录
1、程序目录说明

├── bin │ └── main.py #程序入口 ├── config │ └── settings.py #配置文件,数据库的一些配置信息 └── src #src目录主要放一些和业务相关的方法 ├── auth │ ├── task.py #创建/删除任务 │ ├── type_permission.py #查看用户权限、为某个角色分配权限 │ ├── user.py #添加/删除用户 │ └── user_type.py #添加/删除角色 ├── repository #repository目录主要放操作数据库的方法 定义不同的类 │ ├── permission.py #操作权限表的类 │ ├── user_info.py #操作用户信息的表的类 │ ├── user_type.py #操作角色表的类 │ └── user_type_to_permission.py #操作权限和角色对应关系的类 ├── service.py #主程序 ├── test.py └── utils #utils 目录主要放一些公共模块 ├── commons.py ├── db_connection.py #连接和关闭数据库
2、程序代码
2、1 main.py

#!/usr/bin/env python # -*- coding:utf-8 -*- import os import sys BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASEDIR) from src import service if __name__ == '__main__': service.execute()
2、2 settings.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # 当前登录用户的权限列表 # ... current_user_permission_list = [] # 当前登录用户的基本信息: # {'nid':1,'username': 'root', 'role_id': 1} current_user_info = {} PY_MYSQL_CONN_DICT = { "host": 'xx.xx.xx.xx', "port": 3306, "user": 'root', "passwd": 'xxxxx', "db": 'xxxx', "charset": 'utf8' } # import pymysql # # pymysql.connect(**kwargs) # pymysql.connect(host='localhost',port=3306) # pymysql.connect(**{'host':'locahost','port': 3306})
2、3 task.py

def add_task(): print('开始创建任务') def del_task(): print('开始删除任务')
2、4 type_permission.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.repository.user_info import UserInfoRepository from src.repository.permission import PermissionRepository from src.repository.user_type import UserTypeRepository from src.repository.user_type_to_permission import UserTypeToPermissionRepository def look_per(): ''' 查看用户目前拥有的所有权限 :return: ''' obj_user=UserInfoRepository() obj_type_per = UserTypeToPermissionRepository() username=input("请输入需要查看的用户:") userinfo=obj_user.fetch_by_user(username) type_id=userinfo['user_type_id'] pers=obj_type_per.fetch_permission_by_type_id(type_id) #获取用户所有权限信息 print("{:>8}{}所有权限信息如下:".format('',username)) for i in pers: print('{:>8}{}.'.format('',i['caption'])) def add_per(): ''' 为某个角色分配权限,删除权限暂未写 :return: ''' obj_per=PermissionRepository() obj_type=UserTypeRepository() obj_type_per=UserTypeToPermissionRepository() pers=obj_per.fetch_all() #从permission表中获取所有权限列表 types=obj_type.get_info()#从user_type表中获取所有角色列表 print("{:>8}目前可以管理的角色信息如下:".format('')) for i in types: print(i['nid'],i['caption']) type_id = input("请输入需要管理角色的id:") print("{:>8}目前可以分配的角色信息如下:".format('')) for i in pers: print(i['nid'],i['caption']) per_id = input("请输入需要分配权限的id:") obj_type_per.add(user_type_id=type_id,permission_id=per_id) print("{:>8}权限分配成功".format(''))
2、5 user.py

#!/usr/bin/env python # -*- coding:utf-8 -*- # from src.repository.user_info import UserInfoRepository from src.repository.user_type import UserTypeRepository ''' 实现向user_info表中添加和删除用户 ''' def add_user(): print('{:>8}请输入以下信息创建用户'.format('')) obj_user = UserInfoRepository() obj_type = UserTypeRepository() types = obj_type.get_info() name = input('请输入用户名:') passwd = input('请输入密码:') print('{:>8}角色列表如下:'.format('')) for i in types: print(i['nid'],i['caption']) typeid = input('请选择角色id:') obj_user.add(username=name,passwd=passwd,user_type_id=typeid) print('{:>8}成功创建用户'.format('')) def del_user(): obj = UserInfoRepository() name = input('请输入需要删除的用户名:') obj.dele(name) print('{:>8}成功删除用户'.format(''))
2、6 user_type.py

from src.repository.user_type import UserTypeRepository ''' 实现向user_type表中添加和删除角色 ''' def add_type(): caption = input('请输入角色名:') # 执行SQL语句 obj = UserTypeRepository() obj.add(caption) print('{:>8}角色添加成功'.format('')) def del_type(): caption = input('请输入需要删除角色名:') # 执行SQL语句 obj = UserTypeRepository() obj.del_role(caption) print('{:>8}角色删除成功'.format(''))
2、7 permission.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.utils.db_connection import DbConnection class PermissionRepository: def __init__(self): self.db_conn = DbConnection() def add(self, **kwargs): ''' 添加权限 :param kwargs: :return: ''' cursor = self.db_conn.connect() sql = """ insert into permission(%s) values(%s)""" key_list = [] value_list = [] for k, v in kwargs.items(): key_list.append(k) value_list.append('%%(%s)s' % k) sql = sql % (','.join(key_list), ','.join(value_list)) cursor.execute(sql, kwargs) self.db_conn.close() def fetch_all(self): cursor = self.db_conn.connect() sql = """ select nid, caption, module, func from permission """ cursor.execute(sql) result = cursor.fetchall() self.db_conn.close() return result
2、8 user_info.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.utils.db_connection import DbConnection class UserInfoRepository: def __init__(self): self.db_conn = DbConnection() def add(self, **kwargs): ''' 新增用户 :param kwargs: :return: ''' cursor = self.db_conn.connect() sql = """ insert into user_info(%s) values(%s)""" key_list = [] value_list = [] for k, v in kwargs.items(): key_list.append(k) value_list.append('%%(%s)s' % k) sql = sql % (','.join(key_list), ','.join(value_list)) cursor.execute(sql, kwargs) self.db_conn.close() def dele(self, name): ''' 根据用户名删除用户 :param name: :return: ''' cursor = self.db_conn.connect() sql = "delete from user_info WHERE username=%s" cursor.execute(sql, name) self.db_conn.close() def fetch_by_user_pwd(self, username, password): """ 根据用户名密码获取账户信息、角色类型 :param username: :param password: :return: """ cursor = self.db_conn.connect() sql = """ select user_info.nid as nid, user_info.username as username, user_info. user_type_id as user_type_id, user_type.caption as user_type_caption from user_info left join user_type on user_info.user_type_id=user_type.nid where user_info.username=%s and user_info.passwd=%s """ cursor.execute(sql, [username, password, ]) result = cursor.fetchone() self.db_conn.close() return result def fetch_by_user(self, username): """ 仅根据用户名获取账户信息、角色类型 :param username: :param password: :return: """ cursor = self.db_conn.connect() sql = """ select user_info.nid as nid, user_info.username as username, user_info. user_type_id as user_type_id, user_type.caption as user_type_caption from user_info left join user_type on user_info.user_type_id=user_type.nid where user_info.username=%s """ cursor.execute(sql, username) result = cursor.fetchone() self.db_conn.close() return result def exist(self, username): ''' 根据用户名判断用户是否存在 :param username: :return: ''' sql = "select 1 from user_info where username=%s" cursor = self.db_conn.connect() cursor.execute(sql, [username,]) result = cursor.fetchone() self.db_conn.close() return result
2、9 user_type.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.utils.db_connection import DbConnection class UserTypeRepository: def __init__(self): self.db_conn = DbConnection() def add(self, caption): """ 在user_type表中添加角色 :param caption: :return: """ cursor = self.db_conn.connect() sql = """ insert into user_type(caption) values(%s) """ cursor.execute(sql, [caption,]) self.db_conn.close() def del_role(self,role): """ 在user_type表中删除角色 :param role: :return: """ cursor = self.db_conn.connect() sql = "delete from user_type WHERE caption=%s" cursor.execute(sql, role) self.db_conn.close() def get_info(self): """ 获取user_type表中所有用户角色类型 :return: """ cursor = self.db_conn.connect() sql='select * from user_type' cursor.execute(sql) result = cursor.fetchall() self.db_conn.close() return result
2.10 user_type_to_permission.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.utils.db_connection import DbConnection class UserTypeToPermissionRepository: def __init__(self): self.db_conn = DbConnection() def add(self, **kwargs): ''' 在user_type_to_permission表中添加角色和权限的对应关系 :param kwargs: :return: ''' cursor = self.db_conn.connect() sql = """ insert into user_type_to_permission(%s) values(%s)""" key_list = [] value_list = [] for k, v in kwargs.items(): key_list.append(k) value_list.append('%%(%s)s' % k) sql = sql % (','.join(key_list), ','.join(value_list)) cursor.execute(sql, kwargs) self.db_conn.close() def fetch_permission_by_type_id(self, user_type_id): ''' 根据用户角色id获取所拥有的的权限 :param user_type_id: :return: ''' cursor = self.db_conn.connect() sql = """ select permission.nid as nid, permission.caption as caption, permission.module as module, permission.func as func from user_type_to_permission left join permission on user_type_to_permission.permission_id = permission.nid where user_type_to_permission.user_type_id = %s """ cursor.execute(sql, user_type_id) result = cursor.fetchall() self.db_conn.close() return result
2.11 db_connection.py

#!/usr/bin/env python # -*- coding:utf-8 -*- import pymysql from config import settings class DbConnection: def __init__(self): self.__conn_dict = settings.PY_MYSQL_CONN_DICT self.conn = None self.cursor = None def connect(self, cursor=pymysql.cursors.DictCursor): self.conn = pymysql.connect(**self.__conn_dict) self.cursor = self.conn.cursor(cursor=cursor) return self.cursor def close(self): self.conn.commit() self.cursor.close() self.conn.close()
2.12 service.py

#!/usr/bin/env python # -*- coding:utf-8 -*- from src.repository.user_info import UserInfoRepository from src.repository.user_type_to_permission import UserTypeToPermissionRepository from src.repository.user_type import UserTypeRepository from src.utils import commons from config import settings import importlib def choice_menu(): print('登陆成功:%s' % settings.current_user_info['username']) while True: for i, item in enumerate(settings.current_user_permission_list, 1): print(i, item['caption']) choice = input('请输入菜单:') choice = int(choice) # 获取当前选中的权限 permission = settings.current_user_permission_list[choice - 1] # 获取模块路径 module = permission['module'] # 获取方法名 func_name = permission['func'] # 动态导入模块,并通过反射执行指定的方法 m = importlib.import_module(module) func = getattr(m, func_name) func() def find_pwd(): pass def register(): # 输入用户名 # 输入密码 # 输入邮箱 # 判断用户名是否存在 obj_type = UserTypeRepository() types = obj_type.get_info() name = input('请输入用户名:') passwd = input('请输入密码:') print('{:>8}角色列表如下:'.format('')) for i in types: print(i['nid'], i['caption']) typeid = input('请选择角色id:') obj_user = UserInfoRepository() ret = obj_user.exist(name) if ret: print('已经存在') else: obj_user.add(username=name, passwd=passwd, user_type_id=typeid) print('{:>8}成功创建用户'.format('')) # 将数据插入到userinfo表 def login(): while True: username = input('请输入用户名:') password = input('请输入密码:') #pwd = commons.md5(password) pwd=password user_repository = UserInfoRepository() # 当前登录的用户信息 user_info = user_repository.fetch_by_user_pwd(username, pwd) if not user_info: print('用户名或密码错误,请重新输入.') continue type_to_per_repository = UserTypeToPermissionRepository() # 获取登录用户的权限信息 permission_list = type_to_per_repository.fetch_permission_by_type_id(user_info['user_type_id']) # 将当前用户权限信息保存到配置中 settings.current_user_permission_list = permission_list # 将当前用户信息保存到配置中 settings.current_user_info = user_info return True def execute(): while True: print('欢迎登陆权限管理系统:1:登陆;2:注册\n') dic = { '1': login, '2': register, '3': find_pwd, } choice = input('请输入选项:') if choice not in dic.keys(): print('选项输入错误') continue func = dic[choice] # 调用登录login方法,获取返回值 result = func() # if result: # 登录成功后,显示所有菜单 choice_menu()
三、程序测试

注册 欢迎登陆权限管理系统:1:登陆;2:注册 请输入选项:2 请输入用户名:张三 请输入密码:123 角色列表如下: 1 超级管理员 2 普通管理员 4 只读用户 请选择角色id:2 成功创建用户 删除用户 欢迎登陆权限管理系统:1:登陆;2:注册 请输入选项:1 请输入用户名:root 请输入密码:abc 登陆成功:root 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:2 请输入需要删除的用户名:张三 成功删除用户 添加用户 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:1 请输入以下信息创建用户 请输入用户名:李四 请输入密码:123 角色列表如下: 1 超级管理员 2 普通管理员 4 只读用户 请选择角色id:4 成功创建用户 添加角色 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:3 请输入角色名:读写用户 角色添加成功 删除角色 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:4 请输入需要删除角色名:读写用户 角色删除成功 权限管理 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:5 目前可以管理的角色信息如下: 1 超级管理员 2 普通管理员 4 只读用户 请输入需要管理角色的id:2 目前可以分配的角色信息如下: 1 添加用户 2 删除用户 5 添加角色 6 删除角色 7 新建工单 8 删除工单 9 权限管理 10 查看权限 请输入需要分配权限的id:8 权限分配成功 查看权限 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 请输入菜单:6 请输入需要查看的用户:root root所有权限信息如下: 添加用户. 删除用户. 添加角色. 删除角色. 权限管理. 查看权限. 新建工单 欢迎登陆权限管理系统:1:登陆;2:注册 请输入选项:1 请输入用户名:root 请输入密码:abc 登陆成功:root 1 添加用户 2 删除用户 3 添加角色 4 删除角色 5 权限管理 6 查看权限 7 新建工单 请输入菜单:7 开始创建任务
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)