表结构设计

  • 一、权限控制表结构设计
    • 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)

完美的项目从完美的表开始相关推荐

  1. 【开源掌机】百问网DShanMCU-Mio开源掌机(爻-澪)项目,完美支持运行10多个模拟器!

    众筹说明 定金翻倍,即定金19.9元,在付尾款时可抵40元(成品售价不会超过120元)!达标当天就开搞,满100人加速搞尽量在年前发货,让大家先玩起来!如果不达标则原路退款,项目取消. 众筹时间:20 ...

  2. 【众筹】百问网DShanMCU-Mio开源掌机(爻-澪)项目,完美支持运行10多个模拟器!

    众筹说明 定金翻倍,即定金19.9元,在付尾款时可抵40元(成品售价不会超过120元)!达标当天就开搞,满100人加速搞尽量在年前发货,让大家先玩起来!如果不达标则原路退款,项目取消. 众筹时间:20 ...

  3. 软件项目第一次Sprint评分表

    软件项目第一次Sprint评分表 组名:JYJe族                                      姓名:陈杰.周雪莹.孟祥娟 1.本阶段目标是否明确? 组名 分数 原因 9 ...

  4. 第3周 实践项目2 建设”顺序表“算法库(可参考为模板)

    /* *Copyright (c) 2017,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:项目2 -建设"顺序表算法库" *作 者:邵雪源 ...

  5. 数据结构上机实践第三周项目2 - 建设“顺序表”算法库

    [项目2 - 建设"顺序表"算法库]  领会"0207将算法变程序"部分建议的方法,建设自己的专业基础设施算法库.这一周,建的是顺序表的算法库.  算法库包括两 ...

  6. SSM8==纯注解SSM项目:实现单表CRUD、事务、自定义异常和统一异常处理、RESTFUL风格接口、统一返回值格式(状态码、内容、消息)、JSON传参、axios、vue.js、elementUI

    环境:IDEA2021+JDK8+MAVEN3.8+TOMCAT7插件 前端:axios.vue.js.elementUI 后端:见POM.XML相关依赖,主要有数据库MySQL5.7 ,数据源Dru ...

  7. 1、软件项目规划过程——所有表集合

    目录 规划软件项目表 估计项目成本和规模表 制定项目计划表 确定项目风险和管理计划表 规划软件项目表 阶段 时间安排 任务 立项阶段 1周 定义项目范围.目标和需求 计划阶段 2周 制定项目计划.时间 ...

  8. 一个开发周期为6个月的中小型软件开发项目成本预算大致表

    一个开发周期为6个月的中小型软件开发项目成本预算大致表 从Excel粘贴过来,有些变形,请谅解一下. 表格中未包含 管理费用.公司的办公场地费用.税费等,软件的开发成本还是很高 的,能有效控制开发成本 ...

  9. 学生德育实践(自选项目)结题表

    学生德育实践(自选项目)结题表 项目名称: 辛勤劳动,体验生活 立题时间: 2018年9月1日-2019年1月1日 项目负责人: 分 院: 专业班级: 指导老师: 联系方式: 项目名称 辛勤劳动,体验 ...

最新文章

  1. 怎样学好网络(1)-正确的定位
  2. Django04: ORM配置与使用MySQL数据库
  3. js ajax 访问java函数,将url分配给Java EE项目中的ajax(js)函数
  4. the source attachment does not contain the source for the file xxx.class无法关联到某个类
  5. [C++11] 智能指针
  6. golang,break跳出循环的例子以及随机数生成
  7. java 动画 制作_【轻松一刻】Java制作字符动画
  8. 安装MinGW-W64提示cannot download repository.txt
  9. 大话FPGA-“万能的芯片?”
  10. Fiddler+Android7.0+python+requests获取app评论内容《完美解决了代理后打开app没有网络的问题!!!》JustTrustMe+VirtualXposed工具的使用
  11. echarts如何在柱状图上显示百分比
  12. 用c语言编程二元一次方程组的根,c++用函数写输入abc求二元一次方程根
  13. 可以发热的“电”羽绒服!60秒升温15度,自带充电宝,脏了还能机洗
  14. python pyecharts 合并地图_Python pyecharts 绘制的交通拥堵情况地图
  15. 网络安全--SQL注入介绍
  16. HotSwap和JRebel原理
  17. SharedObject对象聊天室
  18. 中国能不能写出操作系统?
  19. 023 TripleGan的合成癫痫脑活动2022
  20. 应届生找工作---简历篇

热门文章

  1. 51 nod 1049 最大子段和 (简单dp)
  2. 在Golang开发中使用Redis
  3. Arduino学习笔记36
  4. Python第四章__装饰器、迭代器
  5. hihoCoder 1052 基因工程 最详细的解题报告
  6. 领域驱动第四章-读书笔记
  7. js修改style中某个属性_JS 和 CSS 交互的 5 种方法
  8. 10-5 4-6 查询在具有最小内存容量的所有PC中具有最快处理器的PC制造商 (10 分)
  9. 【JavaScript DOM 编程艺术】 笔记
  10. F - 娜娜梦游仙境系列——多民族王国