CRM项目开发(一)
http://www.cnblogs.com/runner1/articles/6289723.html
Django的admin已经为我们做好了,很完善的后台管理体系,但页面过于丑陋,自定义的能力还是有局限性的。特此,重写admin后台管理体系,同时也是考虑到其他轻量级框架并没有类似Django这么完善的admin!写成独立的app,便宜更好的进行复用迁移。
创建工程和项目
命名根据自己的喜好吧,推荐使用PyCharm进行创建,减少一些配置操作,当然不要忘记在settings.py的一些配置哦!
我的目录结构:
#由于是在windows下的操作,只能显示以下结构 ├─consultant #销售 │ ├─migrations │ │ └─__pycache__ │ └─__pycache__ ├─CRM #主app │ ├─migrations │ │ └─__pycache__ │ └─__pycache__ ├─king_admin #重构的admin │ ├─migrations │ │ └─__pycache__ │ ├─templatetags │ │ └─__pycache__ │ └─__pycache__ ├─PrefectCRM_new #工程 │ └─__pycache__ ├─statics │ ├─css │ ├─imgs │ ├─js │ └─plugins ├─student #学生 │ ├─migrations │ │ └─__pycache__ │ └─__pycache__ ├─templates │ ├─consultant │ ├─king_admin │ └─student └─utils
由于在数据库表中,绑定了一些路由映射关系,顺便将路由的结构也显示一下:
#这是总的urls.py中的配置,独立将在下面一次贴出来 from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^crm/', include('CRM.urls')), url(r'^student/', include('student.urls')), url(r'^consultant/', include('consultant.urls')), url(r'^king_admin/', include('king_admin.urls')), ]
表结构设计
表结构设计是非常关键的步骤,也是最难点!这会影响你以后的程序设计,稍有疏漏,很可能会导致你要进行代码重构或者一路填坑。。。
由于要做的是CRM系统,这里就以XXX公司作为案例。
在进行具体的代码之前,我们先进行一些数据关系的处理,这里推荐大家使用ER图(ER图的使用请自行Google)。我这里是通过先前搞好的数据结构和ER图,就不在重复赘述,直接上处理好后的图和代码:
ER思维导图:

数据关系图:


在主app,CRM中的models.py中创建数据结构:
from django.db import models from django.contrib.auth.models import User # Create your models here. class Customer(models.Model): '''客户信息表''' name = models.CharField(max_length=32,blank=True,null=True) qq = models.CharField(max_length=64,unique=True) qq_name = models.CharField(max_length=64,blank=True,null=True) phone = models.CharField(max_length=64,blank=True,null=True) source_choices = ((0,'转介绍'), (1,'QQ群'), (2,'官网'), (3,'百度推广'), (4,'51CTO'), (5,'知乎'), (6,'市场推广') ) source = models.SmallIntegerField(choices=source_choices) referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) consult_course = models.ForeignKey("Course",verbose_name="咨询课程") content = models.TextField(verbose_name="咨询详情") tags = models.ManyToManyField("Tag",blank=True) status_choices = ((0,'已报名'), (1,'未报名'), ) status = models.SmallIntegerField(choices=status_choices,default=1) consultant = models.ForeignKey("UserProfile") memo = models.TextField(blank=True,null=True) date = models.DateTimeField(auto_now_add=True) def __str__(self): return self.qq class Meta: verbose_name ="客户表" verbose_name_plural ="客户表" class Tag(models.Model): name = models.CharField(unique=True,max_length=32) def __str__(self): return self.name class Meta: verbose_name = "标签" verbose_name_plural = "标签" class CustomerFollowUp(models.Model): '''客户跟进表''' customer = models.ForeignKey("Customer") content = models.TextField(verbose_name="跟进内容") consultant = models.ForeignKey("UserProfile") intention_choices = ((0,'2周内报名'), (1,'1个月内报名'), (2,'近期无报名计划'), (3,'已在其它机构报名'), (4,'已报名'), (5,'已拉黑'), ) intention = models.SmallIntegerField(choices=intention_choices) date = models.DateTimeField(auto_now_add=True) def __str__(self): return "<%s : %s>" %(self.customer.qq,self.intention) class Meta: verbose_name = '客户追踪' verbose_name_plural = "客户追踪" class Course(models.Model): '''课程表''' name = models.CharField(max_length=64,unique=True) price = models.PositiveSmallIntegerField() period = models.PositiveSmallIntegerField(verbose_name="周期(月)") outline = models.TextField() def __str__(self): return self.name class Meta: verbose_name = "课程表" verbose_name_plural = "课程表" class Branch(models.Model): '''校区''' name = models.CharField(max_length=128,unique=True) addr = models.CharField(max_length=128) def __str__(self): return self.name class Meta: verbose_name = "校区" verbose_name_plural = "校区" class ClassList(models.Model): '''班级表''' branch = models.ForeignKey("Branch",verbose_name="校区") course = models.ForeignKey("Course") class_type_choices = ((0,'面授(脱产)'), (1,'面授(周末)'), (2,'网络班') ) class_type = models.SmallIntegerField(choices=class_type_choices,verbose_name="班级类型") semester = models.PositiveSmallIntegerField(verbose_name="学期") teachers = models.ManyToManyField("UserProfile") start_date = models.DateField(verbose_name="开班日期") end_date = models.DateField(verbose_name="结业日期",blank=True,null=True) def __str__(self): return "%s %s %s" %(self.branch,self.course,self.semester) class Meta: unique_together = ('branch','course','semester') verbose_name_plural = "班级" verbose_name = "班级" class CourseRecord(models.Model): '''上课记录''' from_class = models.ForeignKey("ClassList",verbose_name="班级") day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") teacher = models.ForeignKey("UserProfile") has_homework = models.BooleanField(default=True) homework_title = models.CharField(max_length=128,blank=True,null=True) homework_content = models.TextField(blank=True,null=True) outline = models.TextField(verbose_name="本节课程大纲") date = models.DateField(auto_now_add=True) def __str__(self): return "%s %s" %(self.from_class,self.day_num) class Meta: unique_together = ("from_class", "day_num") verbose_name_plural = "上课记录" class StudyRecord(models.Model): '''学习记录''' student = models.ForeignKey("Enrollment") course_record = models.ForeignKey("CourseRecord") attendance_choices = ((0,'已签到'), (1,'迟到'), (2,'缺勤'), (3,'早退'), ) attendance = models.SmallIntegerField(choices=attendance_choices,default=0) 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"), ) score = models.SmallIntegerField(choices=score_choices,default=0) memo = models.TextField(blank=True,null=True) date = models.DateField(auto_now_add=True) def __str__(self): return "%s %s %s" %(self.student,self.course_record,self.score) class Meta: unique_together = ('student','course_record') verbose_name_plural = "学习记录" class Enrollment(models.Model): '''报名表''' customer = models.ForeignKey("Customer") enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级") consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问") contract_agreed = models.BooleanField(default=False,verbose_name="学员已同意合同条款") contract_approved = models.BooleanField(default=False,verbose_name="合同已审核") date = models.DateTimeField(auto_now_add=True) def __str__(self): return "%s %s" %(self.customer,self.enrolled_class) class Meta: unique_together = ("customer","enrolled_class") verbose_name_plural = "报名表" class Payment(models.Model): '''缴费记录''' customer = models.ForeignKey("Customer") course = models.ForeignKey("Course",verbose_name="所报课程") amount = models.PositiveIntegerField(verbose_name="数额",default=500) consultant = models.ForeignKey("UserProfile") date = models.DateTimeField(auto_now_add=True) def __str__(self): return "%s %s" %(self.customer,self.amount) class Meta: verbose_name_plural = "缴费记录" class UserProfile(models.Model): '''账号表''' user = models.OneToOneField(User) name = models.CharField(max_length=32) roles = models.ManyToManyField("Role",blank=True) def __str__(self): return self.name class Meta: verbose_name_plural = '用户账号' class Role(models.Model): '''角色表''' name = models.CharField(max_length=32,unique=True) menus = models.ManyToManyField("Menu",blank=True) def __str__(self): return self.name class Meta: verbose_name_plural = "角色" class Menu(models.Model): '''菜单''' name = models.CharField(max_length=32) url_name = models.CharField(max_length=64) def __str__(self): return self.name class Meta: verbose_name_plural = '菜单栏'
1.以上内容只是作为参考,并一定能够作为生产上的应用,若要上生产还要考虑更多的因素,这里是为写CRM提供一种通用的思路。
2.如果你考虑到以后的数据会很大,那建议你对数据进行拆分,每个独立的app中进行独自的表结构设计,然后在主app中进行处理
原生Django的admin分析
在进行分析之前,我们需要创建超级用户,然后登陆到后台中,添加一些测试数据。
admin初始化操作
创建超级用户
>>> python manage.py createsuperuser<br> #下面的用户名和密码自己耍吧!
注册admin
其实,创建完用户我们就已经可以进入到后台了,将写好数据表models.py里面的类注册CRM项目的admin.py中,并进行一些简单的自定义操作:
from django.contrib import admin from CRM import models # Register your models here. #注册操作 admin.site.register(models.Branch) admin.site.register(models.ClassList) admin.site.register(models.Course) admin.site.register(models.CourseRecord) admin.site.register(models.Customer) admin.site.register(models.CustomerFollowUp) admin.site.register(models.Enrollment) admin.site.register(models.Payment) admin.site.register(models.Role) admin.site.register(models.StudyRecord) admin.site.register(models.UserProfile) admin.site.register(models.Tag) admin.site.register(models.Menu)
登陆admin后台
以下是将数据库表结构设计好后的显示效果,其中添加了一些测试数据:


自定义显示样式
我们在上面看到客户表中显示的内容太过稀少,而且功能也是少的可怜,好在Django为我们提供了自定义功能。
同样在admin.py中进行自定义操作:
from django.contrib import admin from CRM import models # Register your models here. #自定义操作 class CustomerAdmin(admin.ModelAdmin): list_display = ('name', 'id','qq','source','consultant','content','status','date') list_filter = ('source','consultant','date') search_fields = ('qq','name') raw_id_fields = ('consult_course',) filter_horizontal = ('tags',) list_editable = ('status',) class UserProfileAdmin(admin.ModelAdmin): list_display = ('user','name') #注册操作 #注册操作 admin.site.register(models.Branch) admin.site.register(models.ClassList) admin.site.register(models.Course) admin.site.register(models.CourseRecord) admin.site.register(models.Customer, CustomerAdmin) #这里要添加自定义操作 admin.site.register(models.CustomerFollowUp) admin.site.register(models.Enrollment) admin.site.register(models.Payment) admin.site.register(models.Role) admin.site.register(models.StudyRecord) admin.site.register(models.UserProfile, UserProfileAdmin) #这里要添加自定义操作 admin.site.register(models.Tag) admin.site.register(models.Menu)

在这里我们能看到很多功能,搜索,过滤,自定义操作action,排序,分页(数据量多时),添加等等。下面的文章中,就进行重构这些功能!

浙公网安备 33010602011771号