前言: 今晚写一篇关于学员/讲师/销售员CRM系统。这个小项目是27号开始做的,大概搞了一星期不到。我把一些知识点总结下,还写下当时克服的BUG。

 

Django练习小项目:学员管理系统设计开发

带着项目需求学习是最有趣和效率最高的,今天就来基于下面的需求来继续学习Django 

项目需求:

  1. 分讲师\学员\课程顾问角色
  2. 学员可以属于多个班级,学员成绩按课程分别统计
  3. 每个班级至少包含一个或多个讲师
  4. 一个学员要有状态转化的过程 ,比如未报名前,报名后,毕业老学员
  5. 客户要有咨询纪录, 后续的定期跟踪纪录也要保存
  6. 每个学员的所有上课出勤情况\学习成绩都要保存
  7. 学校可以有分校区,默认每个校区的员工只能查看和管理自己校区的学员
  8. 客户咨询要区分来源

拿到需求后,先要分析,再设计表结构: 超级重要!!

  1 from django.db import models
  2 
  3 from django.contrib.auth.models import User  #django自带的用户认证表
  4 # Create your models here.
  5 course_type_choice = (("online", u"网络班"),
  6                       ("offline_weekend", u"面授班(周末)"),
  7                       ("offline_fulltime", u"面授班(脱产)"),
  8                       )  # 课程类型
  9 
 10 class School(models.Model):  #学校表
 11     name = models.CharField(max_length=128, unique=True)
 12     city = models.CharField(max_length=64)
 13     addr = models.CharField(max_length=128)
 14 
 15     def __str__(self):  #给前端界面显示学校名
 16         return self.name
 17 
 18 
 19 class UserProfile(models.Model):  #内部员工表
 20     # User是一张表,在UserProfile关联User表,类似继承User表,也可以拓展别的字段
 21     # 这里不能用ForeignKey(一对多),比如User表里有一个zcl,
 22     # 用FK,则可以在UserProfile创建多个zcl用户,实际上UserProfile应当只有一个用户
 23     # 用OneToOne关联,只能有一个UserProfile用户与User关联,其它用户不能关联,
 24     # 在数据库层面OneToOne与ForeignKey实现是相同的,都是用FK, OneToOne是django admin层面做限制的
 25     user = models.OneToOneField(User,verbose_name=u"登陆用户名")
 26     name = models.CharField(max_length=64, verbose_name=u"全名")
 27     school = models.ForeignKey("School")  #比如领导可以管理多个学校,但有些老师就只能对应一个学校
 28     user_type_choice = (("salespeople", u"销售员"),
 29                         ("teachers", u"讲师"),
 30                         ("others", u"其它"),
 31                         )
 32     user_type = models.CharField(verbose_name=u"用户类型",max_length=64, choices=user_type_choice, default="others")
 33 
 34     def __str__(self):
 35         return self.name
 36 
 37     class Meta:
 38         # 加上权限。can_del_customer是存在数据库中的,"可以删除用户"是显示在界面的
 39         # permissions = (("can_del_customer",u"可以删除用户"),)
 40         # 加入三条权限
 41         permissions = (("view_customer_list",u"可以查看客户列表"),  # 对销售员的权限
 42                        ("view_customer_info", u"可以查看客户详情"),
 43                        ("edit_own_customer_info", u"可以修改自己的客户信息"),
 44 
 45                        ("view_class_list", u"可以查看班级列表"),  # 对讲师的权限
 46                        ("view_class_info", u"可以查看班级详情"),
 47                        ("edit_own_class_info", u"可以修改自己的班级信息"),
 48 
 49                        )
 50 
 51 
 52 class CustomerTrackRecord(models.Model):  #客户跟踪记录表
 53     customer = models.ForeignKey("Customer")  #一个客户可有多个跟踪记录
 54     track_record = models.TextField(u"跟踪记录")
 55     track_date = models.DateField(auto_now_add=True)  #跟踪日期
 56     tracker = models.ForeignKey(UserProfile)  #一条跟踪记录只能有一个追踪人
 57     status_choices = ((1, u"近期无报名计划"),
 58                       (2, u"2个月内报名"),
 59                       (3, u"1个月内报名"),
 60                       (4, u"2周内报名"),
 61                       (5, u"1周内报名"),
 62                       (6, u"2天内报名"),
 63                       (7, u"已报名"),
 64                       )
 65     status = models.IntegerField(u"状态",choices=status_choices,help_text=u"选择客户此时的状态")
 66 
 67     def __str__(self):
 68         return self.customer.qq
 69 
 70 
 71 class Course(models.Model):  #课程表
 72     name = models.CharField(max_length=64, unique=True)  #课程名
 73     online_price = models.IntegerField()  #网络班课程价格
 74     offline_price = models.IntegerField()  #面授班课程价格
 75     introduction = models.TextField()  #课程介绍
 76 
 77     def __str__(self):
 78         return self.name
 79 
 80 
 81 class ClassList(models.Model):  # 班级表
 82     course = models.ForeignKey(Course, verbose_name=u"课程")  # 关联课程表
 83     semester = models.IntegerField(verbose_name=u"学期")
 84     teachers = models.ManyToManyField(UserProfile, verbose_name=u"讲师")  # 多对多关联
 85     start_date = models.DateField(verbose_name=u"开班日期")  # 开班日期
 86     graduate_date = models.DateField(blank=True,null=True)  # 结业日期
 87     # 课程类型
 88     course_type = models.CharField(max_length=64, choices=course_type_choice,default="offline_weekend")
 89 
 90     def __str__(self):
 91         return "%s[%s期][%s]" % (self.course, self.semester, self.get_course_type_display())
 92 
 93     class Meta:
 94         # 联合唯一,python网络班15期只能有一个
 95         unique_together = ("course", "semester", "course_type")
 96 
 97 
 98 class Customer(models.Model):  # 学员表
 99     qq = models.CharField(max_length=64, unique=True)
100     # 名字可为空,刚来咨询时不会告诉name
101     name = models.CharField(max_length=64, blank=True, null=True)
102     phone = models.BigIntegerField(blank=True, null=True)  # 不用IntegerField,不够长
103     course = models.ForeignKey("Course")  # 学员咨询的课程,只记录咨询的一个课程,若有多个可备注说明
104     course_type = models.CharField(verbose_name=u"课程类型", max_length=64, choices=course_type_choice, default="offline_weekend")
105     consult_memo = models.TextField(verbose_name=u"咨询备注")  # 咨询内容
106     source_type_choice = (("qq", u"qq群"),
107                           ("referral", u"内部转介绍"),
108                           ("51CTO", u"51CTO"),
109                           ("agent", u"招生代理"),
110                           ("others", u"其它"),
111                           )  #客户来源
112     source_type = models.CharField(max_length=64, choices=source_type_choice, default="others")
113     # 表示自关联(Customer表关联Customer表),也可用referral_from = models.ForeignKey("Customer")
114     # 1.加上self  2.自关联要加上related_name,通过internal_referral反查数据
115     # 反向关联得加上related_name: eg:A介绍B来上课,对A通过referral_from可找到B;反之需通过referral
116     # 该字段表示该学生被谁介绍来上课的
117     referral_from = models.ForeignKey("self", blank=True, null=True, related_name="referral")
118 
119     status_choices = (("singed", u"已报名"),
120                       ("unregistered", u"未报名"),
121                       ("graduated", u"已毕业"),
122                       ("drop_off", u"退学"),
123                       )  # 客户来源
124     status = models.CharField(max_length=64, choices=status_choices, default="unregistered")
125     consultant = models.ForeignKey("UserProfile", verbose_name="课程顾问")
126     date = models.DateField(u"咨询日期", auto_now_add=True)  # auto_now_add创建时自动添加当前日期
127     class_list = models.ManyToManyField("ClassList", blank=True)  # 对于多对多字段,不需要null=true
128 
129     def __str__(self):
130         return "%s[%s]" % (self.qq, self.name)
131 
132 
133 class CourseRecord(models.Model):  # 上课记录表
134     class_obj = models.ForeignKey(ClassList)  # 关联班级
135     day_num = models.IntegerField(u"第几节课")
136     course_date = models.DateField(auto_now_add=True, verbose_name=u"上课时间")
137     teacher = models.ForeignKey(UserProfile)  # 讲师
138 
139     # students = models.ManyToManyField(Customer) 不能在这里多对多,if do this,can't 查看出勤情况
140     def __str__(self):
141         return "%s[day%s]" % (self.class_obj, self.day_num)
142 
143     class Meta:  # 联合唯一  python自动化12期网络班 12;只能有一个12天
144         unique_together = ("class_obj", "day_num")
145 
146 
147 class StudyRecord(models.Model):
148     # 关联上课记录表,上课记录表有第几节课字段,同时也与ClassList关联,可知道是哪个班第几期
149     course_record = models.ForeignKey(CourseRecord)
150     student = models.ForeignKey(Customer)  # 关联学员表
151     record_choices = (('checked', u"已签到"),
152                       ('late',u"迟到"),
153                       ('no_show',u"缺勤"),
154                       ('leave_early',u"早退"),
155                       )
156     record = models.CharField(u"状态", choices=record_choices,default="no_show",max_length=64)
157     score_choices = ((100, 'A+'),
158                      (90,'A'),
159                      (85,'B+'),
160                      (80,'B'),
161                      (70,'B-'),
162                      (60,'C+'),
163                      (50,'C'),
164                      (40,'C-'),
165                      (0,'D'),
166                      (-1,'N/A'),  # 暂无成绩
167                      (-100,'COPY'),
168                      (-1000,'FAIL'),
169                      )
170     score = models.IntegerField(u"本节成绩",choices=score_choices,default=-1)
171     date = models.DateTimeField(auto_now_add=True)
172     note = models.CharField(u"备注",max_length=255,blank=True,null=True)
173 
174     def __str__(self):
175         return "%s,%s,%s" % (self.course_record,self.student,self.get_record_display())
View Code

相关文章:

  • 2021-11-20
  • 2021-07-25
  • 2021-11-24
  • 2021-11-02
  • 2021-05-21
  • 2021-12-31
猜你喜欢
  • 2022-01-23
  • 2021-11-14
  • 2021-10-09
  • 2021-10-09
  • 2021-10-16
相关资源
相似解决方案