Djangoadmin已经为我们做好了,很完善的后台管理体系,但页面过于丑陋,自定义的能力还是有局限性的。特此,重写admin后台管理体系,同时也是考虑到其他轻量级框架并没有类似Django这么完善的admin!写成独立的app,便宜更好的进行复用迁移。

1. 创建工程和项目

命名根据自己的喜好吧,推荐使用PyCharm进行创建,减少一些配置操作,当然不要忘记在settings.py的一些配置!

目录结构如下:

├─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
由于在数据库表中,绑定了一些路由映射关系,顺便将路由的结构也显示一下:
 1 #这是总的urls.py中的配置,独立将在下面一次贴出来
 2 from django.conf.urls import url,include
 3 from django.contrib import admin
 4 urlpatterns = [
 5     url(r\'^admin/\', admin.site.urls),
 6     url(r\'^crm/\', include(\'CRM.urls\')),
 7     url(r\'^student/\', include(\'student.urls\')),
 8     url(r\'^consultant/\', include(\'consultant.urls\')),
 9     url(r\'^king_admin/\', include(\'king_admin.urls\')),
10 ]

 

2. 表结构设计

表结构设计是非常关键的步骤,也是最难点!这会影响你以后的程序设计,稍有疏漏,很可能会导致你要进行代码重构或者一路填坑…

由于要做的是CRM系统,这里就以XXX公司作为案例。

在进行具体的代码之前,我们先进行一些数据关系的处理,这里推荐大家使用ER图(mac上我使用MindNode)。我这里是通过先前搞好的数据结构和ER图,就不在重复赘述,直接上处理好后的图和代码: 

ER思维导图:

数据关系图:

 在主appCRM中的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,blank=True,null=True)
  7     qq = models.CharField(max_length=64,unique=True)
  8     qq_name = models.CharField(max_length=64,blank=True,null=True)
  9     phone = models.CharField(max_length=64,blank=True,null=True)
 10     source_choices = ((0,\'转介绍\'),
 11                       (1,\'QQ群\'),
 12                       (2,\'官网\'),
 13                       (3,\'百度推广\'),
 14                       (4,\'51CTO\'),
 15                       (5,\'知乎\'),
 16                       (6,\'市场推广\')
 17                       )
 18     source = models.SmallIntegerField(choices=source_choices)
 19     referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True)
 20     consult_course = models.ForeignKey("Course",verbose_name="咨询课程")
 21     content = models.TextField(verbose_name="咨询详情")
 22     tags = models.ManyToManyField("Tag",blank=True)
 23     status_choices = ((0,\'已报名\'),
 24                       (1,\'未报名\'),
 25                       )
 26     status = models.SmallIntegerField(choices=status_choices,default=1)
 27     consultant = models.ForeignKey("UserProfile")
 28     memo = models.TextField(blank=True,null=True)
 29     date = models.DateTimeField(auto_now_add=True)
 30     def __str__(self):
 31         return self.qq
 32     class Meta:
 33         verbose_name ="客户表"
 34         verbose_name_plural ="客户表"
 35 class Tag(models.Model):
 36     name = models.CharField(unique=True,max_length=32)
 37     def __str__(self):
 38         return self.name
 39     class Meta:
 40         verbose_name = "标签"
 41         verbose_name_plural = "标签"
 42 class CustomerFollowUp(models.Model):
 43     \'\'\'客户跟进表\'\'\'
 44     customer = models.ForeignKey("Customer")
 45     content = models.TextField(verbose_name="跟进内容")
 46     consultant = models.ForeignKey("UserProfile")
 47     intention_choices  = ((0,\'2周内报名\'),
 48                           (1,\'1个月内报名\'),
 49                           (2,\'近期无报名计划\'),
 50                           (3,\'已在其它机构报名\'),
 51                           (4,\'已报名\'),
 52                           (5,\'已拉黑\'),
 53                           )
 54     intention = models.SmallIntegerField(choices=intention_choices)
 55     date = models.DateTimeField(auto_now_add=True)
 56     def __str__(self):
 57         return "<%s : %s>" %(self.customer.qq,self.intention)
 58     class Meta:
 59         verbose_name = \'客户追踪\'
 60         verbose_name_plural = "客户追踪"
 61 class Course(models.Model):
 62     \'\'\'课程表\'\'\'
 63     name = models.CharField(max_length=64,unique=True)
 64     price = models.PositiveSmallIntegerField()
 65     period = models.PositiveSmallIntegerField(verbose_name="周期(月)")
 66     outline = models.TextField()
 67     def __str__(self):
 68         return self.name
 69     class Meta:
 70         verbose_name = "课程表"
 71         verbose_name_plural = "课程表"
 72 class Branch(models.Model):
 73     \'\'\'校区\'\'\'
 74     name = models.CharField(max_length=128,unique=True)
 75     addr = models.CharField(max_length=128)
 76     def __str__(self):
 77         return self.name
 78     class Meta:
 79         verbose_name = "校区"
 80         verbose_name_plural = "校区"
 81 class ClassList(models.Model):
 82     \'\'\'班级表\'\'\'
 83     branch = models.ForeignKey("Branch",verbose_name="校区")
 84     course = models.ForeignKey("Course")
 85     class_type_choices = ((0,\'面授(脱产)\'),
 86                           (1,\'面授(周末)\'),
 87                           (2,\'网络班\')
 88                           )
 89     class_type = models.SmallIntegerField(choices=class_type_choices,verbose_name="班级类型")
 90     semester = models.PositiveSmallIntegerField(verbose_name="学期")
 91     teachers = models.ManyToManyField("UserProfile")
 92     start_date = models.DateField(verbose_name="开班日期")
 93     end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
 94     def __str__(self):
 95         return "%s %s %s" %(self.branch,self.course,self.semester)
 96     class Meta:
 97         unique_together = (\'branch\',\'course\',\'semester\')
 98         verbose_name_plural = "班级"
 99         verbose_name = "班级"
100 class CourseRecord(models.Model):
101     \'\'\'上课记录\'\'\'
102     from_class = models.ForeignKey("ClassList",verbose_name="班级")
103     day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)")
104     teacher = models.ForeignKey("UserProfile")
105     has_homework = models.BooleanField(default=True)
106     homework_title = models.CharField(max_length=128,blank=True,null=True)
107     homework_content = models.TextField(blank=True,null=True)
108     outline = models.TextField(verbose_name="本节课程大纲")
109     date = models.DateField(auto_now_add=True)
110     def __str__(self):
111         return "%s %s" %(self.from_class,self.day_num)
112     class Meta:
113         unique_together = ("from_class", "day_num")
114         verbose_name_plural = "上课记录"
115 class StudyRecord(models.Model):
116     \'\'\'学习记录\'\'\'
117     student = models.ForeignKey("Enrollment")
118     course_record = models.ForeignKey("CourseRecord")
119     attendance_choices = ((0,\'已签到\'),
120                           (1,\'迟到\'),
121                           (2,\'缺勤\'),
122                           (3,\'早退\'),
123                           )
124     attendance = models.SmallIntegerField(choices=attendance_choices,default=0)
125     score_choices = ((100,"A+"),
126                      (90,"A"),
127                      (85,"B+"),
128                      (80,"B"),
129                      (75,"B-"),
130                      (70,"C+"),
131                      (60,"C"),
132                      (40,"C-"),
133                      (-50,"D"),
134                      (-100,"COPY"),
135                      (0,"N/A"),
136                      )
137     score = models.SmallIntegerField(choices=score_choices,default=0)
138     memo = models.TextField(blank=True,null=True)
139     date = models.DateField(auto_now_add=True)
140     def __str__(self):
141         return "%s %s %s" %(self.student,self.course_record,self.score)
142     class Meta:
143         unique_together = (\'student\',\'course_record\')
144         verbose_name_plural = "学习记录"
145 class Enrollment(models.Model):
146     \'\'\'报名表\'\'\'
147     customer = models.ForeignKey("Customer")
148     enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级")
149     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问")
150     contract_agreed = models.BooleanField(default=False,verbose_name="学员已同意合同条款")
151     contract_approved = models.BooleanField(default=False,verbose_name="合同已审核")
152     date = models.DateTimeField(auto_now_add=True)
153     def __str__(self):
154         return "%s %s" %(self.customer,self.enrolled_class)
155     class Meta:
156         unique_together = ("customer","enrolled_class")
157         verbose_name_plural = "报名表"
158 class Payment(models.Model):
159     \'\'\'缴费记录\'\'\'
160     customer = models.ForeignKey("Customer")
161     course = models.ForeignKey("Course",verbose_name="所报课程")
162     amount = models.PositiveIntegerField(verbose_name="数额",default=500)
163     consultant = models.ForeignKey("UserProfile")
164     date = models.DateTimeField(auto_now_add=True)
165     def __str__(self):
166         return "%s %s" %(self.customer,self.amount)
167     class Meta:
168         verbose_name_plural = "缴费记录"
169 class UserProfile(models.Model):
170     \'\'\'账号表\'\'\'
171     user = models.OneToOneField(User)
172     name = models.CharField(max_length=32)
173     roles = models.ManyToManyField("Role",blank=True)
174     def __str__(self):
175         return self.name
176     class Meta:
177         verbose_name_plural = \'用户账号\'
178 class Role(models.Model):
179     \'\'\'角色表\'\'\'
180     name = models.CharField(max_length=32,unique=True)
181     menus = models.ManyToManyField("Menu",blank=True)
182     def __str__(self):
183         return self.name
184     class Meta:
185         verbose_name_plural = "角色"
186 class Menu(models.Model):
187     \'\'\'菜单\'\'\'
188     name = models.CharField(max_length=32)
189     url_name = models.CharField(max_length=64)
190     def __str__(self):
191         return self.name
192     class Meta:
193         verbose_name_plural = \'菜单栏\'

1.以上内容只是作为参考,并不一定能够作为生产上的应用,若要上生产还要考虑更多的因素,这里是为写CRM提供一种通用的思路。
2.如果你考虑到以后的数据会很大,那建议你对数据进行拆分,每个独立的app中进行独自的表结构设计,然后在主app中进行处理

 

3. 原生Django的admin分析

在进行分析之前,我们需要创建超级用户,然后登陆到后台中,添加一些测试数据。

3.1 admin初始化操作

 

 

3.1.1. 创建超级用户

1 >>> python  manage.py  createsuperuser
2 #下面的用户名和密码自己耍吧!

 

3.1.2. 注册admin

其实,创建完用户我们就已经可以进入到后台了,将写好数据表models.py里面的类注册CRM项目的admin.py中,并进行一些简单的自定义操作:

 1 from django.contrib import admin
 2 from CRM import models
 3 # Register your models here.
 4 #注册操作
 5 admin.site.register(models.Branch)
 6 admin.site.register(models.ClassList)
 7 admin.site.register(models.Course)
 8 admin.site.register(models.CourseRecord)
 9 admin.site.register(models.Customer)
10 admin.site.register(models.CustomerFollowUp)
11 admin.site.register(models.Enrollment)
12 admin.site.register(models.Payment)
13 admin.site.register(models.Role)
14 admin.site.register(models.StudyRecord)
15 admin.site.register(models.UserProfile)
16 admin.site.register(models.Tag)
17 admin.site.register(models.Menu)

 

3.1.3. 登陆admin后台

以下是将数据库表结构设计好后的显示效果,其中添加了一些测试数据:

 

3.2 自定义显示样式

 

我们在上面看到客户表中显示的内容太过稀少,而且功能也是少的可怜,好在Django为我们提供了自定义功能。

同样在admin.py中进行自定义操作:

支持中文:

1 \'django.contrib.sessions.middleware.SessionMiddleware\',
2 \'django.middleware.locale.LocaleMiddleware\',    # 设置admin为中文,必须放在django.contrib.sessions....之后

 

修改时区:

1 LANGUAGE_CODE = \'en-us\'
2 
3 TIME_ZONE = \'Asia/Shanghai\'    # 设置为东八区的时区
4 
5 USE_I18N = True
6 
7 USE_L10N = True
8 
9 USE_TZ = True

 

 1 from django.contrib import admin
 2 from CRM import models
 3 # Register your models here.
 4 #自定义操作
 5 class CustomerAdmin(admin.ModelAdmin):
 6     list_display = (\'name\', \'id\',\'qq\',\'source\',\'consultant\',\'content\',\'status\',\'date\')
 7     list_filter = (\'source\',\'consultant\',\'date\')
 8     search_fields = (\'qq\',\'name\')
 9     raw_id_fields = (\'consult_course\',)
10     filter_horizontal = (\'tags\',)
11     list_editable = (\'status\',)
12 class UserProfileAdmin(admin.ModelAdmin):
13     list_display = (\'user\',\'name\')
14 #注册操作
15 #注册操作
16 admin.site.register(models.Branch)
17 admin.site.register(models.ClassList)
18 admin.site.register(models.Course)
19 admin.site.register(models.CourseRecord)
20 admin.site.register(models.Customer, CustomerAdmin)  #这里要添加自定义操作
21 admin.site.register(models.CustomerFollowUp)
22 admin.site.register(models.Enrollment)
23 admin.site.register(models.Payment)
24 admin.site.register(models.Role)
25 admin.site.register(models.StudyRecord)
26 admin.site.register(models.UserProfile, UserProfileAdmin)  #这里要添加自定义操作
27 admin.site.register(models.Tag)
28 admin.site.register(models.Menu)

 

 

 

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

 1. 显示内容定制:list_display

2. 过滤功能 list_filter

 

3. 搜索功能 search_fields

4. 字段搜索功能 raw_id_fields

 

5. 字段过滤功能  filter_horizontal

6. 可编辑字段 list_editable

 



版权声明:本文为eaglesour原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/eaglesour/p/8094339.html