完美的项目从完美的表开始
表结构设计
- 一、权限控制表结构设计
- UserInfo
- ScoreRecord
- Attendance
- Team
- Department
- Role
- Permission
- Menu
- 二、业务表结构设计
- User
- Course
- Classes
- Student
- Project
- ProjectRecord
- PaymentRecord
表结构设计是一个项目的基石,组织好各种数据之间的逻辑关系,往往能够使开发事半功倍。
一、权限控制表结构设计
UserInfo
任何项目都要用人使用才有价值,因此设计好用户信息表是第一步。
Django 提供了一个 AbstractUser 类,可以在这个类的基础之上定制我们需要的 model。
我们来看一下这个类的部分源码:
username :用户名
username = models.CharField(_('username'),max_length=150,unique=True,help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),validators=[username_validator],error_messages={'unique': _("A user with that username already exists."),},
)
first_name:名、last_name :姓
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=150, blank=True)
email :邮箱
email = models.EmailField(_('email address'), blank=True)
is_staff :是否为员工
is_staff = models.BooleanField(_('staff status'),default=False,help_text=_('Designates whether the user can log into this admin site.'),
)
is_active :是否处于活动状态
is_active = models.BooleanField(_('active'),default=True,help_text=_('Designates whether this user should be treated as active. ''Unselect this instead of deleting accounts.'),
)
date_joined :加入日期
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
除了 AbstractUser 帮我们定义好的这些属性之外,我们还要自定义一些属性:
gender :成员性别
gender = models.IntegerField(verbose_name='性别', choices=((1, '男'), (2, '女')), default=1)
avatar:成员头像
avatar = models.ImageField(upload_to='avatars/', default='avatars/default.png')
telephone :成员手机号
telephone = models.CharField(max_length=11, null=True, unique=True)
roles:成员所拥有的角色
一个成员可以拥有多个角色,一个角色也可使赋予多个成员,因此 roles 字段应该是多对多的结构。
roles = models.ManyToManyField(verbose_name='拥有的所有角色', to="Role", blank=True)
depart :成员所属部门
一个department只能属于一个部门,根据角色的不同可以拥有该部门负责事务内的权限,而一个部门可以拥有多名成员,因此成员与部门之间是一对多的关系。
department = models.ForeignKey(verbose_name='部门', to="Department", on_delete=models.PROTECT)
organize :成员所属组织
一个成员只能属于一个组织,而一个组织可以拥有多名成员,因此成员与组织之间是一对多的关系。
organize = models.ForeignKey(verbose_name="组织", to="Organize", null=True, blank=True, on_delete=models.PROTECT)
最后,我们的目的想在做这个项目的同时开发出通用的、达到对象级别的权限控制组件,因此我们只借用 AbstractUser 字段而不继承它,确定 UserInfo model 为:
# RBAC/models.py
class UserInfo(models.Model):"""成员信息"""username = models.CharField(verbose_name="用户名", max_length=150, unique=True)first_name = models.CharField(verbose_name="名", max_length=30, blank=True)last_name = models.CharField(verbose_name="姓", max_length=150, blank=True)email = models.EmailField(verbose_name="邮箱", blank=True)score = models.IntegerField(verbose_name="积分", default=10)grade = models.IntegerField(verbose_name="等级", choices=((1, "M1"), (2, "M2"), (3, "M3"), (4, "M4"), (5, "M5")),default=1)gender = models.IntegerField(verbose_name='性别', choices=((1, '男'), (2, '女')), default=1)avatar = models.ImageField(verbose_name="头像", upload_to='avatars/', default='avatars/default.png')telephone = models.CharField(verbose_name='手机号', max_length=11, null=True, unique=True)date_joined = models.DateTimeField(verbose_name="加入日期", default=timezone.now)roles = models.ManyToManyField(verbose_name='拥有的所有角色', to="Role", blank=True)team = models.ForeignKey(verbose_name="组", to="Team", null=True, blank=True, on_delete=models.PROTECT)department = models.ForeignKey(verbose_name='部门', to="Department", null=True, blank=True, on_delete=models.PROTECT)def __str__(self):return self.username
ScoreRecord
工作室共成员分为5个等级,由个人等级积分及相关条件确定,详情见下表:
等级 | 积分要求 | 其他要求 | 备注 |
---|---|---|---|
M1 (white) | 10 | 无 | 新成员初始积分10分 |
M2 (blue) | 100 | 通过基础考试 | 线上答题,随时可尝试 |
M3 (yellow) | 1000 | 至少参与3个项目 | 工作室项目或自己的项目 |
M4 (orange) | 10000 | 能够带队完成项目 | 限定工作室项目 |
M5 (red) | 100000 | 有开源框架贡献 | 在GitHub、CSDN、博客园等社区有一定知名度 |
# RBAC/models.py
class ScoreRecord(models.Model):"""积分记录"""score = models.IntegerField(verbose_name="处理分值")reason = models.TextField(verbose_name="理由")member = models.ForeignKey(verbose_name="成员", to="UserInfo", on_delete=models.PROTECT)referee = models.ForeignKey(verbose_name="执行人", to="UserInfo", on_delete=models.PROTECT)
Attendance
class Attendance(models.Model):"""出勤记录"""subject = models.CharField(verbose_name="主题", max_length=32)member = models.ForeignKey(verbose_name="成员", to="UserInfo", on_delete=models.PROTECT)record = models.CharField("记录", choices=[("check", "全勤"), ("vacate", "请假"), ("late", "迟到"), ("lack", "缺勤")])score = models.IntegerField(verbose_name="处理分值")referee = models.ForeignKey(verbose_name="执行人", to="UserInfo", on_delete=models.PROTECT)def __str__(self):return "%s-%s" % (self.subject, self.member.username)
Matrix工作室划分为6个部门、4个小组,每位成员可同时拥有所属部门和所属分组。
Team
工作室共分四个组:1. 算法组、2. 前端组、3. 后端组、4. AI组
# RBAC/models.py
class Team(models.Model):"""分组信息"""teamName = models.CharField(verbose_name="Team名称", max_length=32, unique=True)introduce = models.TextField(verbose_name="Team介绍")# 一个组内可以拥有多名角色,但一个角色只能属于一个组hasRoles = models.ForeignKey(verbose_name="组内拥有的角色", to="Role", null=True, blank=True, on_delete=models.PROTECT)def __str__(self):return self.teamName
Department
工作室下设六个部门:
1. 项目商谈部
由各组组长组成,负责与甲方商谈项目的需求功能与出价,整理出具体的需求分析报告或导图。
2. 项目开发部
负责每个项目的进度监督、成员安排、整体架构设计和技术解决方案,合理调配各组成员。
3. UI设计部
与项目开发人员沟通,负责前端、移动端页面设计,负责工作室宣传海报、视频的制作。
4. 学院联系部
负责与学院相关部门建立联系,维护工作室为学院制作的有关项目,并负责各种比赛的报名与培训安排。
5. 成员管理部
统一管理各组成员,每月团建,同时负责新成员的培训与学习监督,各组成员之间的流动。
6. 技术委员会
由各组组长和工作室M4、M5级别成员组成,为工作室提供技术支持和技术评审。
# RBAC/models.py
class Department(models.Model):"""部门信息"""departmentName = models.CharField(verbose_name="部门名称", max_length=32, unique=True)duty = models.TextField(verbose_name="部门职责")# 一个部门可以拥有多名角色,但一个角色只能属于一个部门hasRoles = models.ForeignKey(verbose_name="组内拥有的角色", to="Role", null=True, blank=True, on_delete=models.PROTECT)def __str__(self):return self.departmentName
Role
通过角色将成员与权限之间关联起来,不同的成员拥有不同的角色,不同的角色拥有不同的权限。
# RBAC/models.py
class Role(models.Model):"""角色"""roleName = models.CharField(verbose_name="角色名称", max_length=32)permissions = models.ManyToManyField(verbose_name="角色所拥有权限", to='Permission', null=True, blank=True)def __str__(self):return self.roleName
Permission
权限其实就是成员是否具有访问某个 URL 的资格,因此权限的主要字段其实就是 URL。
# RBAC/models.py
class Permission(models.Model):"""权限"""url = models.CharField(verbose_name="权限URL正则表达式", max_length=256)permissionName = models.CharField(verbose_name="权限名称", max_length=32)alias = models.CharField(verbose_name="权限URL别名", max_length=32, unique=True)icon = models.CharField(verbose_name="权限图标", max_length=32)menu = models.ForeignKey(verbose_name="所属菜单", to="Menu", null=True, blank=True, on_delete=models.PROTECT,help_text="如果为 null 表示该权限不是菜单,否则为二级菜单")parentPermission = models.ForeignKey(verbose_name="父权限", to="Permission", null=True, blank=True,related_name="parentPermission", on_delete=models.PROTECT,help_text="非菜单权限需要一个二级菜单的父权限做默认展开和选中")def __str__(self):return self.permissionName
Menu
菜单用于侧边栏展示。
# RBAC/models.py
class Menu(models.Model):"""菜单"""menuName = models.CharField(verbose_name="菜单名称", max_length=32)icon = models.CharField(verbose_name="菜单图标", max_length=32)def __str__(self):return self.menuName
二、业务表结构设计
User
对于非工作室人员注册的账号,其实就是游客,他们也需要一个账号,另外,工作室内部成员有时也是游客,此时,需要为游客创建一张用户表,这时候,我们就可以直接用 AbstractUser 类做继承了:
class User(AbstractUser):"""用户"""avatar = models.ImageField(upload_to='avatars/', default='avatars/default.png')telephone = models.CharField(max_length=11, null=True, blank=True, unique=True)def __str__(self):return self.username
Course
工作室 M4、M5等级的成员可以开设课程,为方便管理,需要创建一张 Course 表。
# index/models.py
class Course(models.Model):"""课程"""courseName = models.CharField(verbose_name="课程名称", max_length=32)sketch = models.TextField(verbose_name="课程简述")price = models.PositiveIntegerField(verbose_name="学费", help_text="游客学习收费,工作室成员学习免费")cover = models.ImageField(verbose_name="课程封面", upload_to='courseCover/', default='courseCover/default.png')grade = models.IntegerField(verbose_name="课程等级", choices=((1, "M1"), (2, "M2"), (3, "M3"), (4, "M4"), (5, "M5")))category = models.IntegerField(verbose_name="课程分类", choices=((1, "算法"), (2, "前端"), (3, "后端"), (4, "AI"), (5, "其它")))teacher = models.ForeignKey(verbose_name="开课老师", to="UserInfo", on_delete=models.PROTECT,help_text="开课老师限制为M4、M5等级成员")assistant = models.ManyToManyField(verbose_name="助教", to="UserInfo",help_text="助教限定为M3等级成员")def __str__(self):return self.courseName
Classes
每一门课程对应一个班级,用于存储一些课程资料、学生交流和老师答疑。
# index/models.py
class Classes(models.Model):"""班级"""startDate = models.DateField(verbose_name="开课日期")QQ = models.IntegerField(verbose_name="班级QQ群")graduateDate = models.DateField(verbose_name="结业日期", null=True, blank=True)explain = models.TextField(verbose_name="说明", null=True, blank=True)course = models.ForeignKey(verbose_name="课程", to="Course", on_delete=models.PROTECT)classTeacher = models.ForeignKey(verbose_name="班主任", to="UserInfo", on_delete=models.PROTECT,help_text="班主任为成员管理部成员,负责督促老师课程制作进度和学生学习进度")def __str__(self):return "%s-%s" % (self.course.courseName, self.QQ)
Student
class Student(models.Model):"""学生表"""student = models.OneToOneField(verbose_name="学生信息", to="User", on_delete=models.PROTECT)QQ = models.CharField(verbose_name="学生QQ", max_length=32)telephone = models.IntegerField(verbose_name="学生手机号", max_length=32)classList = models.ManyToManyField(verbose_name="已报班级", to="Classes", null=True, blank=True)state = models.IntegerField(verbose_name="学生状态", choices=[(1, "审核"), (2, "在读"), (3, "毕业")], default=1)remark = models.TextField(verbose_name="备注")def __str__(self):return "%s-%s" % (self.student.username, self.classList.course.name)
Project
工作室承接项目,需要一个项目表存储项目记录。
class Project(models.Model):"""项目"""name = models.CharField(verbose_name="项目名称", max_length=32)contactName = models.CharField(verbose_name="联系人姓名", max_length=32)contactInformation = models.CharField(verbose_name="联系人联系方式", max_length=64, help_text="QQ/WeChat/Phone")price = models.IntegerField(verbose_name="项目报价")introduce = models.TextField(verbose_name="项目介绍")superintendent = models.ForeignKey(verbose_name="项目负责人", to="UserInfo", null=True, blank=True, on_delete=models.PROTECT)startDate = models.DateField(verbose_name="接取日期", null=True, blank=True)completeDate = models.DateField(verbose_name="完结日期", null=True, blank=True)def __str__(self):return self.name
ProjectRecord
为了保证项目能够保质保量的按时完成,每个项目需要一名项目开发部的成员进行监督和跟进。
class ProjectRecord(models.Model):"""项目跟进记录"""content = models.TextField(verbose_name="跟进内容")date = models.DateField(verbose_name="跟进日期", default=timezone.now)project = models.ForeignKey(verbose_name="跟进项目", to="Project", on_delete=models.PROTECT)superintendent = models.ForeignKey(verbose_name="跟进人", to="UserInfo", on_delete=models.PROTECT)def __str__(self):return "%s-%s" % (self.project.name, self.date)
PaymentRecord
class PaymentRecord(models.Model):"""账单记录"""user = models.OneToOneField(verbose_name="付款人", to="User", on_delete=models.PROTECT)type = models.IntegerField(verbose_name="账单类型", choices=[(1, "学费"), (2, "项目款"), (3, "其它")])price = models.IntegerField(verbose_name="金额")date = models.DateTimeField(verbose_name="账单日期", default=timezone.now)state = models.IntegerField(verbose_name="状态", choices=[(1, "审核中"), (2, "确认"), (3, "驳回")])confirmDate = models.DateTimeField(verbose_name="确认日期", null=True, blank=True)confirmUser = models.ForeignKey(verbose_name="审批人", to="UserInfo", null=True, blank=True, on_delete=models.PROTECT)remark = models.TextField(verbose_name="备注", null=True, blank=True)def __str__(self):return "%s-%s-%s" % (self.user.username, self.type, self.price)
完美的项目从完美的表开始相关推荐
- 【开源掌机】百问网DShanMCU-Mio开源掌机(爻-澪)项目,完美支持运行10多个模拟器!
众筹说明 定金翻倍,即定金19.9元,在付尾款时可抵40元(成品售价不会超过120元)!达标当天就开搞,满100人加速搞尽量在年前发货,让大家先玩起来!如果不达标则原路退款,项目取消. 众筹时间:20 ...
- 【众筹】百问网DShanMCU-Mio开源掌机(爻-澪)项目,完美支持运行10多个模拟器!
众筹说明 定金翻倍,即定金19.9元,在付尾款时可抵40元(成品售价不会超过120元)!达标当天就开搞,满100人加速搞尽量在年前发货,让大家先玩起来!如果不达标则原路退款,项目取消. 众筹时间:20 ...
- 软件项目第一次Sprint评分表
软件项目第一次Sprint评分表 组名:JYJe族 姓名:陈杰.周雪莹.孟祥娟 1.本阶段目标是否明确? 组名 分数 原因 9 ...
- 第3周 实践项目2 建设”顺序表“算法库(可参考为模板)
/* *Copyright (c) 2017,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:项目2 -建设"顺序表算法库" *作 者:邵雪源 ...
- 数据结构上机实践第三周项目2 - 建设“顺序表”算法库
[项目2 - 建设"顺序表"算法库] 领会"0207将算法变程序"部分建议的方法,建设自己的专业基础设施算法库.这一周,建的是顺序表的算法库. 算法库包括两 ...
- SSM8==纯注解SSM项目:实现单表CRUD、事务、自定义异常和统一异常处理、RESTFUL风格接口、统一返回值格式(状态码、内容、消息)、JSON传参、axios、vue.js、elementUI
环境:IDEA2021+JDK8+MAVEN3.8+TOMCAT7插件 前端:axios.vue.js.elementUI 后端:见POM.XML相关依赖,主要有数据库MySQL5.7 ,数据源Dru ...
- 1、软件项目规划过程——所有表集合
目录 规划软件项目表 估计项目成本和规模表 制定项目计划表 确定项目风险和管理计划表 规划软件项目表 阶段 时间安排 任务 立项阶段 1周 定义项目范围.目标和需求 计划阶段 2周 制定项目计划.时间 ...
- 一个开发周期为6个月的中小型软件开发项目成本预算大致表
一个开发周期为6个月的中小型软件开发项目成本预算大致表 从Excel粘贴过来,有些变形,请谅解一下. 表格中未包含 管理费用.公司的办公场地费用.税费等,软件的开发成本还是很高 的,能有效控制开发成本 ...
- 学生德育实践(自选项目)结题表
学生德育实践(自选项目)结题表 项目名称: 辛勤劳动,体验生活 立题时间: 2018年9月1日-2019年1月1日 项目负责人: 分 院: 专业班级: 指导老师: 联系方式: 项目名称 辛勤劳动,体验 ...
最新文章
- 怎样学好网络(1)-正确的定位
- Django04: ORM配置与使用MySQL数据库
- js ajax 访问java函数,将url分配给Java EE项目中的ajax(js)函数
- the source attachment does not contain the source for the file xxx.class无法关联到某个类
- [C++11] 智能指针
- golang,break跳出循环的例子以及随机数生成
- java 动画 制作_【轻松一刻】Java制作字符动画
- 安装MinGW-W64提示cannot download repository.txt
- 大话FPGA-“万能的芯片?”
- Fiddler+Android7.0+python+requests获取app评论内容《完美解决了代理后打开app没有网络的问题!!!》JustTrustMe+VirtualXposed工具的使用
- echarts如何在柱状图上显示百分比
- 用c语言编程二元一次方程组的根,c++用函数写输入abc求二元一次方程根
- 可以发热的“电”羽绒服!60秒升温15度,自带充电宝,脏了还能机洗
- python pyecharts 合并地图_Python pyecharts 绘制的交通拥堵情况地图
- 网络安全--SQL注入介绍
- HotSwap和JRebel原理
- SharedObject对象聊天室
- 中国能不能写出操作系统?
- 023 TripleGan的合成癫痫脑活动2022
- 应届生找工作---简历篇