开发环境:
- 语言Python3.X以上
- MTV WEB框架 Django
- 前端框架 jQuery+bootstrap
- 数据库 MySQL
运行环境
- 安装Python3.x
- 安装Django
- 除IE8以上的浏览器
项目需求:重写Django Admin的功能,实现对表动态的增删改查,实现权限的动态分配,实现自定义Action,等一系列组件扩展功能
项目功能图:
项目表UML表关系图
models.py表关系创建
1 from django.db import models 2 from django.contrib.auth.models import User 3 # Create your models here. 4 class Customer(models.Model): 5 '''客户信息表''' 6 name = models.CharField(max_length=32,null=True,blank=True) 7 qq = models.CharField(max_length=64,unique=True) 8 qq_name = models.CharField(max_length=64,null=True,blank=True) 9 phone = models.CharField(max_length=64,null=True,blank=True) 10 source_choices = ((0,'转介绍'),(1,'QQ群'),(2,'官网'),(3,'百度推广'),(4,'51cto'),(5,'知乎推荐'),(6,'市场推广')) 11 source = models.SmallIntegerField(choices=source_choices) 12 referral_from = models.CharField(verbose_name='转介绍人QQ',max_length=64,null=True,blank=True) 13 consult_course = models.ForeignKey('Course',verbose_name='咨询课程') 14 content = models.TextField(verbose_name='咨询详情') 15 consultant = models.ForeignKey('UserProfile',verbose_name='销售') 16 tags = models.ManyToManyField('Tag',blank=True,null=True); 17 memo = models.TextField(blank=True,null=True) 18 status_choice = (('signed','已报名'),('unregistered','未报名')) 19 status = models.CharField(max_length=64,choices=status_choice,default='unregistered',verbose_name='客户状态') 20 date = models.DateTimeField(auto_now_add=True) 21 22 class Meta: 23 verbose_name_plural = '客户' 24 25 def __str__(self): 26 return self.name 27 28 class CustomerFollowUp(models.Model): 29 '''客户跟进表''' 30 customer = models.ForeignKey('Customer') 31 content = models.TextField(verbose_name='跟进内容') 32 consultant = models.ForeignKey('UserProfile') 33 intention_choices = ((0,'2周内报名'),(1,'1个月报名'),(2,'近期无报名计划'),(3,'已在其他机构报名'),(4,'已报名'),(5,'已拉黑')) 34 intention = models.SmallIntegerField(choices=intention_choices) 35 date = models.DateTimeField(auto_now_add=True) 36 37 def __str__(self): 38 return '%s %s' % (self.customer.qq, self.intention) 39 40 class Meta: 41 verbose_name_plural = '客户跟进记录' 42 43 class Course(models.Model): 44 '''课程表''' 45 name = models.CharField(max_length=128,unique=True) 46 price = models.PositiveSmallIntegerField() 47 period = models.PositiveSmallIntegerField(verbose_name='周期(月)') 48 outline = models.TextField() 49 50 def __str__(self): 51 return self.name 52 53 class Meta: 54 verbose_name_plural = '课程' 55 56 class Branch(models.Model): 57 '''校区表''' 58 name = models.CharField(max_length=128,unique=True) 59 addr = models.CharField(max_length=512) 60 61 def __str__(self): 62 return self.name 63 64 class Meta: 65 verbose_name_plural = '校区' 66 67 class ClassList(models.Model): 68 '''班级表''' 69 branch = models.ForeignKey('Branch',verbose_name='分校') 70 course = models.ForeignKey('Course') 71 semester = models.PositiveSmallIntegerField(verbose_name='学期') 72 teachers = models.ManyToManyField('UserProfile') 73 class_type_choice = ((0,'面授班(脱产)'),(1,'面授班(周末)'),(2,'网络班')) 74 class_type = models.SmallIntegerField(choices=class_type_choice) 75 start_date = models.DateField(verbose_name='开班日期') 76 end_date = models.DateField(verbose_name='结业日期',blank=True,null=True) 77 78 def __str__(self): 79 return '%s %s %s' % (self.branch, self.course, self.semester) 80 81 class Meta: 82 unique_together = ('branch', 'course', 'semester') 83 verbose_name_plural = '班级' 84 85 86 87 class CourseRecord(models.Model): 88 '''上课记录表''' 89 from_class = models.ForeignKey('ClassList',verbose_name='班级') 90 day_num = models.PositiveSmallIntegerField(verbose_name='第几节(天)') 91 teacher = models.ForeignKey('UserProfile') 92 has_homework = models.BooleanField(default=True) 93 homework_title = models.CharField(max_length=256,blank=True,null=True) 94 homework_content = models.TextField(blank=True,null=True) 95 outline = models.TextField(verbose_name='本节课大纲') 96 date = models.DateTimeField(auto_now_add=True) 97 98 def __str__(self): 99 return '%s %s' % (self.from_class, self.day_num) 100 101 class Meta: 102 unique_together = ('from_class', 'day_num') 103 verbose_name_plural = '上课记录' 104 105 106 class StudyRecord(models.Model): 107 '''学习记录表''' 108 student = models.ForeignKey('Enrollment') 109 course_record = models.ForeignKey('CourseRecord') 110 attendance_choice = ((0,'已签到'),(1,'迟到'),(2,'缺勤'),(3,'早退')) 111 attendance = models.SmallIntegerField(choices=attendance_choice,default=0) 112 score_choices = ((100,'A+'),(90,'A'),(85,'B+'),(80,'B'),(75,'B-'),(70,'C+'),(60,'C'),(40,'C-'),(-50,'D'),(-100,'COPY'),(0,'N/A')) 113 score = models.SmallIntegerField(choices=score_choices) 114 memo = models.TextField(blank=True,null=True) 115 date = models.DateTimeField(auto_now_add=True) 116 117 def __str__(self): 118 return '%s %s %s' % (self.student, self.course_record, self.score) 119 120 class Meta: 121 unique_together = ('student', 'course_record') 122 verbose_name_plural = '学习记录' 123 124 125 126 127 class Enrollment(models.Model): 128 '''学生报名表(学生报名信息,合同,入学日期,所报班级)''' 129 customer = models.ForeignKey('Customer') 130 enrolled_class = models.ForeignKey('ClassList',verbose_name='所报班级') 131 consultant = models.ForeignKey('UserProfile',verbose_name='课程顾问') 132 contact_agreed = models.BooleanField(default=False,verbose_name='学生已同意合同条款') 133 contact_approved = models.BooleanField(default=False,verbose_name='合同已审核') 134 date = models.DateTimeField(auto_now_add=True) 135 136 def __str__(self): 137 return '%s %s' % (self.customer, self.enrolled_class) 138 139 class Meta: 140 unique_together = ('customer', 'enrolled_class') 141 verbose_name_plural = '报名' 142 143 class Payment(models.Model): 144 '''缴费记录''' 145 customer = models.ForeignKey('Customer') 146 course = models.ForeignKey('Course') 147 amount = models.PositiveIntegerField(verbose_name='数额',default=500) 148 consultant = models.ForeignKey('UserProfile') 149 date = models.DateTimeField(auto_now_add=True) 150 151 def __str__(self): 152 return '%s %s' % (self.customer, self.amount) 153 154 class Meta: 155 verbose_name_plural = '缴费记录' 156 157 class UserProfile(models.Model): 158 '''账号表''' 159 user = models.OneToOneField(User) 160 name = models.CharField(max_length=32) 161 roles = models.ManyToManyField('Role',blank=True,null=True) 162 163 def __str__(self): 164 return self.name 165 166 167 class Role(models.Model): 168 '''角色表''' 169 name = models.CharField(max_length=64,unique=True) 170 171 def __str__(self): 172 return self.name 173 174 class Meta: 175 verbose_name_plural = '角色' 176 177 class Tag(models.Model): 178 '''标签备注''' 179 name = models.CharField(max_length=64,unique=True) 180 181 def __str__(self): 182 return self.name 183 class Meta: 184 verbose_name_plural = '标签'
在Settings文件中配置静态文件路径
1 STATIC_URL = '/static/' 2 STATICFILES_DIRS =( 3 os.path.join(BASE_DIR,'static'), 4 )
更改默认的数据库
1 DATABASES = { 2 'default': { 3 'ENGINE': 'django.db.backends.mysql', 4 'NAME': 'prefect_crm', 5 'USER': 'root', 6 'PASSWORD': 'oldboy', 7 'HOST': '127.0.0.1', 8 'PORT': '3306' 9 } 10 }
在app下的__init__.py中插入
1 import pymysql 2 pymysql.install_as_MySQLdb()