西游之路——python全栈——CRM项目之表结构设计

一、表结构设计

  1 from django.db import models
  2 from django.contrib.auth.models import User
  3 
  4 """自带验证"""
  5 class UserProFile(models.Model):
  6     """用户信息表"""
  7     user = models.OneToOneField(User,on_delete=models.CASCADE)
  8     name = models.CharField(max_length=32,verbose_name='姓名')
  9     role = models.ManyToManyField('Role',null=True,blank=True)
 10 
 11     class Meta:
 12         verbose_name_plural = '用户信息表'
 13 
 14     def __str__(self):  # __unicode__
 15         return self.name
 16 
 17 class Role(models.Model):
 18     """角色表"""
 19     name = models.CharField(max_length=64,unique=True)
 20     menus = models.ManyToManyField('Menus', verbose_name='菜单',blank=True)
 21 
 22     class Meta:
 23         verbose_name_plural = '角色表'
 24 
 25     def __str__(self):
 26         return self.name
 27 
 28 class CustomerInfo(models.Model):
 29     """客户信息"""
 30     name = models.CharField(max_length=32,default=None)
 31     contact_type_choices = (
 32         (0,'qq'),
 33         (1,'微信'),
 34         (2,'手机'),
 35     )
 36     contact_type = models.SmallIntegerField(choices=contact_type_choices,default=0)
 37     contact = models.CharField(max_length=64,unique=True)
 38     source_choices = (
 39         (0,'QQ群'),
 40         (1,'51CTO'),
 41         (2,'百度推广'),
 42         (3,'知乎'),
 43         (4,'转介绍'),
 44         (5,'其他'),
 45     )
 46     source = models.SmallIntegerField(choices=source_choices)
 47     referral_from = models.ForeignKey('self',null=True,blank=True,verbose_name='转介绍',on_delete=models.CASCADE)
 48 
 49     consult_courses = models.ManyToManyField('Course',verbose_name='咨询课程')
 50     consult_content = models.TextField(verbose_name='咨询内容')
 51     status_choices = (
 52         (0,'未报名'),
 53         (1,'已报名'),
 54         (2,'已退学'),
 55     )
 56     status = models.SmallIntegerField(choices=status_choices)
 57     consultant = models.ForeignKey('UserProFile',verbose_name='课程顾问',on_delete=models.CASCADE)
 58     date = models.DateField(auto_now_add=True)
 59 
 60     class Meta:
 61         verbose_name_plural = '客户信息表'
 62 
 63     def __str__(self):
 64         return self.name
 65 
 66 class Student(models.Model):
 67     """学员表"""
 68     customer = models.ForeignKey('CustomerInfo',on_delete=models.CASCADE)
 69     class_grade = models.ManyToManyField('ClassList')
 70 
 71     class Meta:
 72         verbose_name_plural = '学员表'
 73 
 74     def __str__(self):
 75         return self.customer
 76 
 77 class CustomerFollowUp(models.Model):
 78     """客户跟踪记录表"""
 79     customer = models.ForeignKey('CustomerInfo',on_delete=models.CASCADE)
 80     content = models.TextField(verbose_name='跟踪内容')
 81     user = models.ForeignKey('UserProFile',verbose_name='跟进人',on_delete=models.CASCADE)
 82     status_choices = (
 83         (0,'近期无报名计划'),
 84         (1,'一个月内报名'),
 85         (2,'2周内报名'),
 86         (3,'已报名'),
 87     )
 88     status = models.SmallIntegerField(choices=status_choices)
 89     date = models.DateField(auto_now_add=True)
 90 
 91     class Meta:
 92         verbose_name_plural = '客户跟踪记录表'
 93 
 94     def __str__(self):
 95         return self.content
 96 
 97 class Course(models.Model):
 98     """课程表"""
 99     name = models.CharField(verbose_name='课程名称',max_length=64,unique=True)
100     price = models.PositiveSmallIntegerField()   # 必须为正
101     period = models.PositiveSmallIntegerField(verbose_name='课程周期(月)',default=5)
102     outline = models.TextField(verbose_name='大纲')
103 
104     class Meta:
105         verbose_name_plural = '课程表'
106 
107     def __str__(self):
108         return self.name
109 
110 class ClassList(models.Model):
111     """班级列表"""
112     branch = models.ForeignKey('Branch',on_delete=models.CASCADE)
113     course = models.ForeignKey('Course',on_delete=models.CASCADE)
114     class_type_choices = (
115         (0,'脱产'),
116         (1,'周末'),
117         (2,'网络班')
118     )
119     class_type = models.SmallIntegerField(choices=class_type_choices)
120     semester = models.SmallIntegerField(verbose_name='学期')
121     teachers = models.ManyToManyField('UserProFile',verbose_name='讲师')
122     start_date = models.DateField('开班日期')
123     graduate_date = models.DateField('毕业日期',blank=True,null=True)
124 
125     class Meta:
126         verbose_name_plural = '班级列表'
127         unique_together = (
128             'course',
129             'semester',
130             'branch',
131             'class_type',
132         )
133 
134     def __str__(self):
135         return '%s(%s)期' %(self.course.name, self.semester)
136 
137 class CourseRecord(models.Model):
138     """上课记录"""
139     class_grade = models.ForeignKey('ClassList',verbose_name='上课班级',on_delete=models.CASCADE)
140     day_num = models.PositiveSmallIntegerField('课程节次')
141     teacher = models.ForeignKey('UserProFile',on_delete=models.CASCADE)
142     title = models.CharField('本节主题',max_length=64)
143     content = models.TextField('本节内容')
144     has_homework = models.BooleanField('本节有作业',default=True)
145     homework = models.TextField('作业需求',blank=True,null=True)
146     date = models.DateTimeField(auto_now_add=True)
147 
148     class Meta:
149         verbose_name_plural = '上课记录'
150         unique_together = (
151             'class_grade',
152             'day_num',
153         )
154 
155     def __str__(self):
156         return '%s第(%s)节' %(self.class_grade, self.day_num)
157 
158 class StudyRecord(models.Model):
159     """学习记录"""
160     course_record = models.ForeignKey('CourseRecord',on_delete=models.CASCADE)
161     student = models.ForeignKey('Student',on_delete=models.CASCADE)
162 
163     score_choices = (
164         (100,'A+'),
165         (90,'A'),
166         (85,'B+'),
167         (80,'B'),
168         (75,'B-'),
169         (70,'C+'),
170         (60,'C'),
171         (40,'C-'),
172         (-50,'D'),
173         (0,'N/A'), # not avaliable
174         (-100,'COPY'),
175     )
176     score = models.SmallIntegerField(choices=score_choices,default=0)
177     show_choices = (
178         (0,'缺勤'),
179         (1,'已签到'),
180         (2,'迟到'),
181         (3,'早退'),
182     )
183     show_status = models.SmallIntegerField(choices=show_choices)
184     note = models.TextField('成绩备注',blank=True,null=True)
185     date = models.DateTimeField(auto_now_add=True)
186 
187     class Meta:
188         verbose_name_plural = '学习记录'
189 
190     def __str__(self):
191         return '%s %s %s'  %(self.course_record,self.student,self.score)
192 
193 class Branch(models.Model):
194     """校区"""
195     name = models.CharField(max_length=64,unique=True)
196     addr = models.CharField(max_length=128,blank=True,null=True)
197 
198     class Meta:
199         verbose_name_plural = '校区'
200 
201     def __str__(self):
202         return self.name
203 
204 class Menus(models.Model):
205     """动态菜单"""
206     name = models.CharField('菜单名',max_length=32)
207     url_type_choices = (
208         (0,'absolute'),
209         (1,'dynamic'),
210     )
211     url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
212     url_name = models.CharField('连接',max_length=128)
213 
214 
215     class Meta:
216         verbose_name_plural = '菜单'
217         unique_together = ('name','url_name')
218 
219     def __str__(self):
220         return self.name
Model.py

总结:

  1、防止以后掉坑,需多花心思设计表结构

  2、先整体把所有表列出,一定给表写注释

  3、在逐一完善字段,并确定个表之间的关系

  4、后续添加

  5、注意细节,变量命名的规范,单复数

  6、日后若想用Django自带验证时,用户需关联Django的User(O2O)

转载于:https://www.cnblogs.com/Lujun1028/p/9832178.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你见过吗?9款超炫的复选框(Checkbox)效果

复选框(Checkbox)在各个浏览器中的效果不一致,因此很多 Web 开发人员会自己重新设计一套界面和使用体验都更佳的复选框功能。下面就给大家分享9款超炫的复选框(Checkbox)效果,纯 CSS3 实现,未使…

实用技巧:使用 Google Analytics 跟踪 JS 错误

Google Analytics(谷歌分析)不仅仅是一个流量统计工具,你还可以用它来测量广告活动的有效性,跟踪用户多远到所需的页面流(从点击广告到购物车到结账页面)获取,并基于用户的信息设置浏览器和语言…

从Ubuntu 14.04 LTS版升级到Ubuntu 16.04 LTS

Ubuntu 16.04 (Xerial Xerus) Long Term Support版于最近发布了。要想了解它的新功能和新特性,就必须升级或安装这个新系统。 本文讲述怎样一步步从Ubuntu 14.04 LTS版升级到Ubuntu 16.04 LTS版。要注意在升级前做好重要数据的备份,以免造成数据损失。因…

HTML5 Dashboard – 那些让你激动的 Web 技术

HTML5 Dashboard 是一个 Mozilla 推出的项目,里面展示了最前沿的 HTML5,CSS3,JavaScript 技术。每一项技术都有简洁,在线演示以及详细的文档链接。这些技术将成为未来一段时间 Web 开发的顶尖技术,如果不想落伍的话就赶…

通过自动回复机器人学Mybatis---基础版

第1章 案例简介 介绍要实现的案例情况,后面会通过这个案例来学习 Mybatis第2章 实战第一部----黎明前的黑暗 在没有 Mybatis 的情况下,使用 Jsp Servlet Jdbc 实现案例中的一个模块开发流程1: 开发流程2: 开发流程3:…

Scroll Depth – 衡量页面滚动的 Google 分析插件

Scroll Depth 是一个小型的 Google Analytics(谷歌分析)插件,可以让你衡量用户在页面上滚动了多远。它可以监控 25%、50%、75% 和 100% 四个滚动点,并发送谷歌分析事件。 您还可以跟踪页面上的特定元素是否滚动到视图中。例如在博…

aws ec2时间_AWS中自动化的三大领域,以避免支付过多的云账单

AWS是全球最常用的云服务之一。 Gartner Magic Quadrant将AWS评为最大的IaaS提供商。每个可能的域都由企业使用AWS服务。 全球约有 1,000,000家公司正在使用AWS作为其IaaS提供商。从Netflix到Unilever再到Met Office,每个人都转移到AWS上的云基础架构。既然您正在阅…

Croppic – 免费开源的 jQuery 图片裁剪插件

Croppic 这款开源的 jQuery 图片裁剪插件能够满足网站开发人员各种不同的使用需要。只需要简单的上传图片,就可以实现你想要的图像缩放和裁剪功能。因为使用了 HTML5 FormData 对象,所以目前只支持 IE 10 、Chrome 和 Firefox 等现代浏览器。 您可能感兴…

应用面向方面的编程

1.引言 面向方面的编程的主要目标是将跨领域的关注点分离。 当我们谈论跨领域的关注时,我们指的是在我们的系统或应用程序中的多个地方使用的通用功能。 这些概念包括: 记录中 交易管理 错误处理 监控方式 安全 实现这种分离的方法是将这些概念模块…

ScrollReveal.js – 帮助你实现超炫的元素运动效果

ScrollReveal.js 用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力。只需要给元素增加 data-scrollreveal 属性,当元素进入可视区域的时候会自动被触发设置好的动画。 您可能感兴趣的相关文章2013年最受欢迎的10篇前端开发博文小伙伴…

JDBC布尔兼容性列表

有趣的是,布尔类型只是在SQL标准后期才引入,即SQL:1999 。 即使在今天,并非所有数据库本身都支持BOOLEAN或BIT类型。 最重要的是,我们仍然可以在Oracle中等待一段时间。 这是2002年以来关于该主题的“问汤姆”的观点&a…

GDI+与WPF中的颜色简析

GDI与WPF中的颜色简析 原文:GDI与WPF中的颜色简析--------------------------------------------------------------------------------引用或转载时请保留以下信息:大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com http://www.brawdraw.com萝卜鼠在线图形…

Panorama Viewer – jQuery 360度全景展示插件

jQuery Panorama Viewer 这款插件可以帮助你在网站中嵌入全景图片。要做到这一点,首先只需要在页面中引入最新的 jQuery 库,以及 jquery.panorama_viewer.js 和 panorama_viewer.css 到页面中,然后给图片添加 CSS 类“panorama”。现代浏览器…

oracle group by 多类别_python数据关系型图表散点图系列多数据系列

多数据系列多数据系列的散点图需要使用不同的填充颜色(fill)和数据点形状(shape)这两个视觉特征来表示数据系列;绘制多数据系列散点图多数据系列散点图就是在单数据系列上添加新的数据系列;使用不同的填充颜色或形状区分数据系列;plotnine绘制…

Web 开发中应用 HTML5 技术的10个实例教程

HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究。借助尖端功能,技术和 API,HTML5 允许你创建响应性、创新性、互动性以及令人惊叹的漂亮网站。更进一步,你也可以…

在单元测试中访问私有字段

首先,让我大声说一下,您需要将代码设计为可测试的,以便通过公共方法测试私有字段。 但是,(“ buts”是人们仍在编程而不是计算机本身的原因,所以在这里很高兴)有时您想要并且应该更改一些私有字…

【LeetCode题解】160_相交链表

目录 160_相交链表描述解法一:哈希表思路Java 实现Python 实现解法二:双指针(推荐)思路Java 实现Python 实现160_相交链表 描述 编写一个程序,找到两个单链表相交的起始节点。 例如,下面的两个链表&#xf…

maya崩溃自动保存路径_maya 使用swig将插件编译成pyd,无缝使用内置数据实现加速计算模块...

前言:原本目的是想寻求一种方式来对cpu计算密集型代码部分进行加速替代,但是maya中mll插件的插件套路在传递参数上会占用大量的io,对于数据比较大的部分也会有相当消耗。如果全部写在c部分又感觉缺乏灵活性,所以琢磨的一种可以在p…

Slip.js – 在触摸屏上实现 Swipe 对列表重新排序

Slip.js 是一个很小的 JavaScript 库,用于实现对触摸屏的互动 Swipe 和对元素重新排序列表(Reordering)。Slip.js 没有任何的依赖,你可以通过自定义 DOM 事件实现重新排序交互。 您可能感兴趣的相关文章Pace.js – 页面加载进度自…

构建和运行Java 8支持

尚未提供对Java 8的Eclipse支持。 如果要使用它,则必须构建它。 Eclipsepedia的JDT Core / Java8页面包含有关使用Eclipse Java开发工具 (JDT)中不断发展的Java 8支持源来设置开发环境的说明。 说明中缺少一些内容; 待会儿我会回圈…