1.需求分析

2.使用组件

django2.0+bootstrap3.37+jquery1.12+mysql8.0

django2.1:https://www.djangoproject.com/

3.表结构设计

models.py

  1 from django.db import models
  2 from django.contrib.auth.models import User
  3 from django.contrib.auth.models import (
  4     BaseUserManager, AbstractBaseUser,PermissionsMixin
  5 )
  6 from django.utils.translation import gettext_lazy as _
  7 from django.utils.safestring import mark_safe
  8
  9 # Create your models here.
 10
 11
 12 class Customer(models.Model):
 13     """客户信息表"""
 14     name = models.CharField(max_length=32,blank=True,null=True,help_text="用户注册后更改")
 15     qq = models.CharField(max_length=64,unique=True)
 16     qq_name = models.CharField(max_length=64,blank=True,null=True)
 17     phone = models.CharField(max_length=64,blank=True,null=True)
 18     id_num = models.CharField(max_length=64,blank=True,null=True)
 19     email = models.EmailField(verbose_name="常用邮箱",blank=True,null=True)
 20     source_choices = ((0,"转介绍"),
 21                       (1,"QQ群"),
 22                       (2,"官网"),
 23                       (3,"百度推广"),
 24                       (4,"51CTO"),
 25                       (5,"知乎"),
 26                       (6,"市场推广")
 27                       )
 28     source = models.SmallIntegerField(choices=source_choices)
 29     referral_form = models.CharField(max_length=64,verbose_name="转介绍人QQ",blank=True,null=True)
 30
 31     consult_course = models.ForeignKey("Course",verbose_name="咨询课程",on_delete=models.CASCADE)
 32     content = models.TextField(verbose_name="咨询详情")
 33     tags = models.ManyToManyField("Tag",blank=True)
 34     status_choices = ((0,'已报名'),(1,'未报名'),)
 35     status = models.SmallIntegerField(choices=status_choices,default=1)
 36     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)
 37     memo = models.TextField(blank=True,null=True)
 38     date = models.DateTimeField(auto_now_add=True)
 39
 40     def __str__(self):
 41         return self.qq
 42
 43     class Meta:
 44         verbose_name = "客户信息表"
 45         verbose_name_plural = "客户信息表"
 46
 47 class Tag(models.Model):
 48     """标签表"""
 49     name = models.CharField(unique=True,max_length=32)
 50
 51     def __str__(self):
 52         return self.name
 53
 54     class Meta:
 55         verbose_name = "标签表"
 56         verbose_name_plural = "标签表"
 57
 58 class CustomerFollowUp(models.Model):
 59     """客户跟踪表"""
 60     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)
 61     content = models.TextField(verbose_name="跟进内容")
 62     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)
 63     intention_choices = ((0,"2周内报名"),
 64                          (1,"1个月内报名"),
 65                          (2,"近期无报名计划"),
 66                          (3,"已在其他机构报名"),
 67                          (4,"已报名"),
 68                          (5,"已拉黑"),
 69                          )
 70     intention = models.SmallIntegerField(choices=intention_choices)
 71     date = models.DateTimeField(auto_now_add=True)
 72
 73     def __str__(self):
 74         return "<%s:%s>"%(self.customer.qq,self.intention)
 75
 76     class Meta:
 77         verbose_name = "客户跟踪表"
 78         verbose_name_plural = "客户跟踪表"
 79
 80 class Course(models.Model):
 81     """课程表"""
 82     name = models.CharField(max_length=64,unique=True)
 83     price = models.PositiveSmallIntegerField()
 84     period = models.PositiveSmallIntegerField(verbose_name="周期(月)")
 85     outline = models.TextField()
 86
 87     def __str__(self):
 88         return self.name
 89     class Meta:
 90         verbose_name = "课程表"
 91         verbose_name_plural ="课程表"
 92
 93 class Branch(models.Model):
 94     """校区表"""
 95     name = models.CharField(max_length=128,unique=True)
 96     addr = models.CharField(max_length=128)
 97     def __str__(self):
 98         return self.name
 99     class Meta:
100         verbose_name = "校区表"
101         verbose_name_plural ="校区表"
102
103 class ClassList(models.Model):
104     """班级表"""
105     branch = models.ForeignKey("Branch",on_delete=models.CASCADE)
106     course = models.ForeignKey("Course",on_delete=models.CASCADE)
107     class_type_choices = ((0,"面授(脱产)"),
108                           (1, "面授(周末)"),
109                           (2, "网络班"))
110     contract = models.ForeignKey("ContractTemplate",on_delete=models.CASCADE,blank=True,null=True)
111     class_type = models.SmallIntegerField(choices=class_type_choices,verbose_name="班级类型")
112     semester = models.PositiveSmallIntegerField(verbose_name="学期")
113     teachers = models.ManyToManyField("UserProfile")
114     start_date = models.DateField(verbose_name="开班日期")
115     end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
116
117     def __str__(self):
118         return "%s %s %s" %(self.branch,self.course,self.semester)
119
120     class Meta:
121         unique_together = ("branch","course","semester")
122         verbose_name = "班级表"
123         verbose_name_plural = "班级表"
124
125 class CourseRecord(models.Model):
126     """上课记录表"""
127     from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE)
128     day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)")
129     teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)
130     has_homework = models.BooleanField(default=True)
131     homework_title = models.CharField(max_length=128,blank=True,null=True)
132     homework_content = models.TextField(blank=True,null=True)
133     out_line = models.TextField(verbose_name="本节课大纲")
134     date =models.DateField(auto_now_add=True)
135
136     def __str__(self):
137         return "%s %s" %(self.from_class,self.day_num)
138     class Meta:
139         unique_together = ("from_class","day_num")
140         verbose_name = "上课记录表"
141         verbose_name_plural = "上课记录表"
142
143 class StudyRecord(models.Model):
144     """学习记录"""
145     student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)
146     course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)
147     attendance_choices = ((0,"已签到"),
148                           (1,"迟到"),
149                           (2,"缺勤"),
150                           (3,"早退"),
151                           )
152     attendance = models.SmallIntegerField(choices=attendance_choices,default=0)
153     score_choices = ((100,"A+"),
154                      (90,"A"),
155                      (85,"B+"),
156                      (80,"B"),
157                      (75,"B-"),
158                      (70,"C+"),
159                      (60,"C"),
160                      (40,"C-"),
161                      (-50,"D"),
162                      (-100,"copy"),
163                      (0,"N/A"),
164                      )
165     score = models.SmallIntegerField(choices=score_choices,default=0)
166     memo = models.TextField(blank=True,null=True)
167     date = models.DateField(auto_now_add=True)
168
169     def __str__(self):
170         return "%s %s %s" %(self.student,self.course_record,self.score)
171     class Meta:
172         unique_together = ("student","course_record")
173         verbose_name = "学习记录"
174         verbose_name_plural = "学习记录"
175
176 class Enrollment(models.Model):
177     """报名表"""
178     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)
179     enrolled_class =models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)
180     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE)
181     contract_agreed = models.BooleanField(default=False,verbose_name="学员已同意合同条款")
182     contract_approved = models.BooleanField(default=False,verbose_name="合同已审核")
183     date =models.DateTimeField(auto_now_add=True)
184
185     def __str__(self):
186         return "%s %s"%(self.customer,self.enrolled_class)
187     class Meta:
188         unique_together = ("customer","enrolled_class")
189         verbose_name = "报名表"
190         verbose_name_plural = "报名表"
191
192 class Payment(models.Model):
193     """缴费记录"""
194     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)
195     course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)
196     amount = models.PositiveIntegerField(verbose_name="数额",default=500)
197     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)
198     date = models.DateTimeField(auto_now_add=True)
199     def __str__(self):
200         return "%s %s"%(self.customer,self.amount)
201     class Meta:
202         verbose_name = "缴费记录"
203         verbose_name_plural = "缴费记录"
204
205 # class UserProfile(models.Model):
206 #     """账号表"""
207 #     user = models.OneToOneField(User,on_delete=models.CASCADE)
208 #     name = models.CharField(max_length=32)
209 #     roles = models.ManyToManyField("Role",blank=True)
210 #
211 #     def __str__(self):
212 #         return self.name
213 #     class Meta:
214 #         verbose_name = "账号表"
215 #         verbose_name_plural = "账号表"
216
217
218 class UserProfileManager(BaseUserManager):
219     def create_user(self, email, name, password=None):
220         """
221         Creates and saves a User with the given email, date of
222         birth and password.
223         """
224         if not email:
225             raise ValueError('Users must have an email address')
226
227         user = self.model(
228             email=self.normalize_email(email),
229             name=name,
230         )
231
232         user.set_password(password)
233         self.is_active = True
234         user.save(using=self._db)
235         return user
236
237     def create_superuser(self, email, name, password):
238         """
239         Creates and saves a superuser with the given email, date of
240         birth and password.
241         """
242         user = self.create_user(
243             email,
244             password=password,
245             name=name,
246         )
247         user.is_admin = True
248         user.save(using=self._db)
249         return user
250
251
252 class UserProfile(AbstractBaseUser,PermissionsMixin):
253     email = models.EmailField(
254         verbose_name='email address',
255         max_length=255,
256         unique=True,
257     )
258     name =models.CharField(max_length=32)
259     password = models.CharField(_('password'), max_length=128,help_text=mark_safe("""<a href='password/'>修改密码</a>"""))
260     is_active = models.BooleanField(default=True)
261     is_admin = models.BooleanField(default=False)
262     roles = models.ManyToManyField("Role",blank=True)
263     objects = UserProfileManager()
264     stu_amount = models.ForeignKey("Customer",on_delete=models.CASCADE,verbose_name="关联客户信息",blank=True,null=True)
265
266     USERNAME_FIELD = 'email'
267     REQUIRED_FIELDS = ['name']
268
269     def __str__(self):
270         return self.email
271
272     # def has_perm(self, perm, obj=None):
273     #     "Does the user have a specific permission?"
274     #     # Simplest possible answer: Yes, always
275     #     return True
276     #
277     # def has_module_perms(self, app_label):
278     #     "Does the user have permissions to view the app `app_label`?"
279     #     # Simplest possible answer: Yes, always
280     #     return True
281
282     @property
283     def is_staff(self):
284         "Is the user a member of staff?"
285         # Simplest possible answer: All admins are staff
286         return self.is_active
287
288
289     class Meta:
290         permissions = (
291             ("can_access_my_course","可以访问我的课程"),
292             ("can_access_studyrecord","可以访问我的学习记录"),
293             ("can_access_homework_detail","可以访问上交作业"),
294         )
295
296 class Role(models.Model):
297     """角色表"""
298     name = models.CharField(max_length=64,unique=True)
299     menus = models.ManyToManyField("Menu",blank=True)
300     def __str__(self):
301         return self.name
302     class Meta:
303         verbose_name = "角色表"
304         verbose_name_plural = "角色表"
305
306 class Menu(models.Model):
307     """菜单表"""
308     name = models.CharField(max_length=32)
309     url_type_choice = ((0,"alias"),(1,"absolute_url"))
310     url_type = models.SmallIntegerField(choices=url_type_choice,default=0)
311     url_name = models.CharField(max_length=64)
312
313     def __str__(self):
314         return self.name
315
316     class Meta:
317         verbose_name = "菜单表"
318         verbose_name_plural = "菜单表"
319
320 class ContractTemplate(models.Model):
321     """合同模板"""
322     name = models.CharField(verbose_name="合同名称",max_length=64,unique=True)
323     template = models.TextField()
324
325     def __str__(self):
326         return self.name

models

备注:

1.使用mysql数据库在setting.py中的设置

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'PerfectCRM','USER': 'root','PASSWORD': "12345",'HOST': '127.0.0.1','PORT': '3306',}
}

2.Django默认使用MySQLdb模块链接MySQL,主动修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码

import pymysql
pymysql.install_as_MySQLdb()

4.django admin的登录

首先设置admin的账号和密码

python manage.py createsuperuser

在admin.py中添加一下代码:

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

View Code

最后效果:

5.django中使用bootstrap

登录bootstrap的网站下载一个模板(网页+css+js)

创建static目录下面创建css、js、img、fonts、plugins文件存放下载下来的文件

在templates中创建html文件,复制模板文件

修改模板文件中的css和js的路径,就OK了

注意:设置urls和views

后续在修改html模板来制作自己需求的html。

我的模板

js+css

 1 <!DOCTYPE html>
 2 <!-- saved from url=(0042)https://v3.bootcss.com/examples/dashboard/ -->
 3 <html lang="zh-CN">
 4   <head>
 5     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6
 7     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 8     <meta name="viewport" content="width=device-width, initial-scale=1">
 9     <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
10     <meta name="description" content="">
11     <meta name="author" content="">
12     <!--link rel="icon" href="https://v3.bootcss.com/favicon.ico"-->
13
14     <title>PerfectCRM</title>
15
16     <!-- Bootstrap core CSS -->
17     <link href="/static/css/bootstrap_3.3.7_css_bootstrap.min.css" rel="stylesheet">
18
19     <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
20     <link href="/static/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
21
22     <!-- Custom styles for this template -->
23     <link href="/static/css/dashboard.css" rel="stylesheet">
24
25     <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
26     <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
27     <script src="/static/js/ie-emulation-modes-warning.js"></script>
28
29
30   </head>
31
32 {% block body %}
33
34 {% endblock %}
35
36     <!-- Bootstrap core JavaScript
37     ================================================== -->
38     <!-- Placed at the end of the document so the pages load faster -->
39     <script src="/static/js/jquery_1.12.4_jquery.min.js"></script>
40     <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
41     <script src="/static/js/bootstrap_3.3.7_js_bootstrap.min.js"></script>
42     <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
43     <script src="/static/js/holder.min.js"></script>
44     <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
45     <script src="/static/js/ie10-viewport-bug-workaround.js"></script>
46
47
48
49 </html>

base.html

  1 {% extends "base.html" %}
  2 {% block body %}
  3 <body>
  4
  5     <nav class="navbar navbar-inverse navbar-fixed-top">
  6       <div class="container-fluid">
  7         <div class="navbar-header">
  8           <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
  9             <span class="sr-only">Toggle navigation</span>
 10             <span class="icon-bar"></span>
 11             <span class="icon-bar"></span>
 12             <span class="icon-bar"></span>
 13           </button>
 14           <a class="navbar-brand" href="https://v3.bootcss.com/examples/dashboard/#">Project name</a>
 15         </div>
 16         <div id="navbar" class="navbar-collapse collapse">
 17           <ul class="nav navbar-nav navbar-right">
 18             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Dashboard</a></li>
 19             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Settings</a></li>
 20             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Profile</a></li>
 21             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Help</a></li>
 22           </ul>
 23           <form class="navbar-form navbar-right">
 24             <input type="text" class="form-control" placeholder="Search...">
 25           </form>
 26         </div>
 27       </div>
 28     </nav>
 29
 30     <div class="container-fluid">
 31       <div class="row">
 32         <div class="col-sm-3 col-md-2 sidebar">
 33           <ul class="nav nav-sidebar">
 34             <li class="active"><a href="https://v3.bootcss.com/examples/dashboard/#">Overview <span class="sr-only">(current)</span></a></li>
 35             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Reports</a></li>
 36             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Analytics</a></li>
 37             <li><a href="https://v3.bootcss.com/examples/dashboard/#">Export</a></li>
 38           </ul>
 39           <ul class="nav nav-sidebar">
 40             <li><a href="https://v3.bootcss.com/examples/dashboard/">Nav item</a></li>
 41             <li><a href="https://v3.bootcss.com/examples/dashboard/">Nav item again</a></li>
 42             <li><a href="https://v3.bootcss.com/examples/dashboard/">One more nav</a></li>
 43             <li><a href="https://v3.bootcss.com/examples/dashboard/">Another nav item</a></li>
 44             <li><a href="https://v3.bootcss.com/examples/dashboard/">More navigation</a></li>
 45           </ul>
 46           <ul class="nav nav-sidebar">
 47             <li><a href="https://v3.bootcss.com/examples/dashboard/">Nav item again</a></li>
 48             <li><a href="https://v3.bootcss.com/examples/dashboard/">One more nav</a></li>
 49             <li><a href="https://v3.bootcss.com/examples/dashboard/">Another nav item</a></li>
 50           </ul>
 51         </div>
 52         <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
 53           <h1 class="page-header">Dashboard</h1>
 54
 55           <div class="row placeholders">
 56             <div class="col-xs-6 col-sm-3 placeholder">
 57               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
 58               <h4>Label</h4>
 59               <span class="text-muted">Something else</span>
 60             </div>
 61             <div class="col-xs-6 col-sm-3 placeholder">
 62               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
 63               <h4>Label</h4>
 64               <span class="text-muted">Something else</span>
 65             </div>
 66             <div class="col-xs-6 col-sm-3 placeholder">
 67               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
 68               <h4>Label</h4>
 69               <span class="text-muted">Something else</span>
 70             </div>
 71             <div class="col-xs-6 col-sm-3 placeholder">
 72               <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
 73               <h4>Label</h4>
 74               <span class="text-muted">Something else</span>
 75             </div>
 76           </div>
 77
 78           <h2 class="sub-header">Section title</h2>
 79           <div class="table-responsive">
 80             <table class="table table-striped">
 81               <thead>
 82                 <tr>
 83                   <th>#</th>
 84                   <th>Header</th>
 85                   <th>Header</th>
 86                   <th>Header</th>
 87                   <th>Header</th>
 88                 </tr>
 89               </thead>
 90               <tbody>
 91                 <tr>
 92                   <td>1,001</td>
 93                   <td>Lorem</td>
 94                   <td>ipsum</td>
 95                   <td>dolor</td>
 96                   <td>sit</td>
 97                 </tr>
 98                 <tr>
 99                   <td>1,002</td>
100                   <td>amet</td>
101                   <td>consectetur</td>
102                   <td>adipiscing</td>
103                   <td>elit</td>
104                 </tr>
105                 <tr>
106                   <td>1,003</td>
107                   <td>Integer</td>
108                   <td>nec</td>
109                   <td>odio</td>
110                   <td>Praesent</td>
111                 </tr>
112                 <tr>
113                   <td>1,003</td>
114                   <td>libero</td>
115                   <td>Sed</td>
116                   <td>cursus</td>
117                   <td>ante</td>
118                 </tr>
119                 <tr>
120                   <td>1,004</td>
121                   <td>dapibus</td>
122                   <td>diam</td>
123                   <td>Sed</td>
124                   <td>nisi</td>
125                 </tr>
126                 <tr>
127                   <td>1,005</td>
128                   <td>Nulla</td>
129                   <td>quis</td>
130                   <td>sem</td>
131                   <td>at</td>
132                 </tr>
133                 <tr>
134                   <td>1,006</td>
135                   <td>nibh</td>
136                   <td>elementum</td>
137                   <td>imperdiet</td>
138                   <td>Duis</td>
139                 </tr>
140                 <tr>
141                   <td>1,007</td>
142                   <td>sagittis</td>
143                   <td>ipsum</td>
144                   <td>Praesent</td>
145                   <td>mauris</td>
146                 </tr>
147                 <tr>
148                   <td>1,008</td>
149                   <td>Fusce</td>
150                   <td>nec</td>
151                   <td>tellus</td>
152                   <td>sed</td>
153                 </tr>
154                 <tr>
155                   <td>1,009</td>
156                   <td>augue</td>
157                   <td>semper</td>
158                   <td>porta</td>
159                   <td>Mauris</td>
160                 </tr>
161                 <tr>
162                   <td>1,010</td>
163                   <td>massa</td>
164                   <td>Vestibulum</td>
165                   <td>lacinia</td>
166                   <td>arcu</td>
167                 </tr>
168                 <tr>
169                   <td>1,011</td>
170                   <td>eget</td>
171                   <td>nulla</td>
172                   <td>Class</td>
173                   <td>aptent</td>
174                 </tr>
175                 <tr>
176                   <td>1,012</td>
177                   <td>taciti</td>
178                   <td>sociosqu</td>
179                   <td>ad</td>
180                   <td>litora</td>
181                 </tr>
182                 <tr>
183                   <td>1,013</td>
184                   <td>torquent</td>
185                   <td>per</td>
186                   <td>conubia</td>
187                   <td>nostra</td>
188                 </tr>
189                 <tr>
190                   <td>1,014</td>
191                   <td>per</td>
192                   <td>inceptos</td>
193                   <td>himenaeos</td>
194                   <td>Curabitur</td>
195                 </tr>
196                 <tr>
197                   <td>1,015</td>
198                   <td>sodales</td>
199                   <td>ligula</td>
200                   <td>in</td>
201                   <td>libero</td>
202                 </tr>
203               </tbody>
204             </table>
205           </div>
206         </div>
207       </div>
208     </div>
209
210     </body>
211 {% endblock %}

index.html

实际效果:

6.crm中的动态菜单的功能

目的:红线部分为动态生成的菜单部分

1.需要在models中添加一张表menu表关联role

 1 class Role(models.Model):
 2     """角色表"""
 3     name = models.CharField(max_length=64,unique=True)
 4     menus = models.ManyToManyField("Menu",blank=True)
 5     def __str__(self):
 6         return self.name
 7     class Meta:
 8         verbose_name = "角色表"
 9         verbose_name_plural = "角色表"
10
11 class Menu(models.Model):
12     """菜单表"""
13     name = models.CharField(max_length=32)
14     url_name = models.CharField(max_length=64)
15
16     def __str__(self):
17         return self.name
18
19     class Meta:
20         verbose_name = "菜单表"
21         verbose_name_plural = "菜单表"

View Code

2.在账号表、角色表、菜单表中添加数据

3.新建html文件customer,在index文件中循环菜单

1 {% extends "index.html" %}
2
3 {% block page-content %}
4 客户库
5 {% endblock %}

customer

 1    <div class="container-fluid">
 2       <div class="row">
 3         <div class="col-sm-3 col-md-2 sidebar">
 4           <ul class="nav nav-sidebar">
 5               {% for role in request.user.userprofile.roles.all %}
 6                 {% for menu in role.menus.all %}
 7                     <li class=""><a href="{% url menu.url_name %}">{{ menu.name }}</a></li>
 8                 {% endfor %}
 9               {% endfor %}
10           </ul>

index

利用不同的url这样就实现了不同的角色登录不同的页面。

转载于:https://www.cnblogs.com/garrett0220/articles/9369744.html

CRM系统-----学员管理系统相关推荐

  1. CRM系统-----学员管理系统---admin自定义开发3

    admin的自定制开发 18.django实现自定义用户认证 1 from django.db import models 2 from django.contrib.auth.models impo ...

  2. CRM系统-----学员管理系统---admin自定义开发2

    7.admin的自定制开发 10.实现与django admin filter_horizontal一样的复选框 实现效果: 首先要在king_admin中添加    filter_horizonta ...

  3. 客户关系管理系统 java_Java高级项目实战02:客户关系管理系统CRM系统模块分析与介绍...

    先来CRM系统结构图: 每个模块作用介绍如下: 1.营销管理 营销机会管理:针对企业中客户的质询需求所建立的信息录入功能,方便销售人员进行后续的客户需求跟踪与联系,提高企业客户购买产品的几率. 营销开 ...

  4. 【分享】如何自动同步企业微信外部客户信息到CRM系统?

    许多企业的销售人员利用企业微信添加外部客户,与客户沟通,但是销售添加外部客户后并不加外部客户录入到企业CRM中.另外,即便是录入了客户到企业CRM系统中,也经常不去更新外部联系人的信息变化到企业CRM ...

  5. 计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署

    计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署 计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署 本源码技术栈 ...

  6. crm系统是什么很棒ec实力_CRM系统都有哪些功能?CRM管理系统的主要用途又是什么?...

    就目前市面上的CRM系统众多,各个供应商可能都是不太一样的,但是大致上还是离不开这几个功能:即营销自动化.客户管理.销售管理.客服你管理.报表分析等. 其中,销售自动化功能可以说是每个CRM系统的核心 ...

  7. C语言 项目 CRM系统(客户信息管理系统)

    项目目标 项目需求说明 系统界面 1)添加客户界面 通过编号来区分客户 2)删除客户界面 对用户输入的编号进行核查,存在与否,合法与否 3)显示客户列表界面 4)修改客户信息的界面 项目设计 Cust ...

  8. python面相对象编程超市系统_python面向对象编程: 面向对象版学员管理系统

    转载自https://www.cnblogs.com/LynHome/archive/2020/04/06/12650318.html 详细解读请参考https://www.cnblogs.com/b ...

  9. crm管理系统是什么意思 crm系统全称是什么 - whale帷幄

    whale 帷幄营销云 「帷幄营销云」为品牌客户提供一站式的数字营销运营解决方案.它以行业最佳实践为基础,整合内容创意.营销玩法.人群智选.全域投放.营销 ROI 分析于一体:在满足市场营销人员对平台 ...

最新文章

  1. Linux中查看所有正在运行的进程
  2. centOS7 Minima无法上网解决方案(Linux设置开机自动获取ip地址)
  3. flask和ajax,Flask flash和url_用于AJAX
  4. 非公平锁和公平锁在reetrantlock里的实现过程是怎样的
  5. Sentinel(十四)之控制台
  6. 通过设计国际象棋游戏来了解策略模式
  7. facebook.com_如何降低电子商务的Facebook CPM
  8. 钱大妈关闭所有北京门店:低估了北京市场的难度
  9. 电池图标不见了怎么解决
  10. SparkContext详述
  11. 基于python车牌识别系统_GitHub - DataXujing/vehicle-license-plate-recognition: 基于Python的车牌检测和识别系统:...
  12. 与大数据同行—学习和教育的未来 - 电子书下载(高清版PDF格式+EPUB格式)
  13. 基于java+ssh+mysql实现的共享自行车单车租赁|出租管理系统项目源代码
  14. IntelliJ IDEA 2017 汉化包
  15. 数据表对应关系(一对一、一对多、多对多)
  16. vue3的逻辑复用抽离
  17. 百钱买小鸡/*公鸡5文钱1只,母鸡三文钱一只,小鸡一文钱三只。现在用100文钱共买了100只鸡,问这100只鸡中,公鸡,母鸡,小鸡各是多少只?
  18. 戴尔服务器r740硬盘指示灯,戴尔R740服务器获取cpu、内存、硬盘参数信息。
  19. 耳部穴位取穴 耳朵对应身体各部位反射图
  20. Google 应用与游戏出海 4 月刊: 带您连线 GDC,赢在发布前!

热门文章

  1. CSS 实现自动等分圆效果
  2. 微信服务器向公众号推送消息或事件后,微信服务器向公众号推送消息或事件后,得到的回应不合法?...
  3. 病毒性的抱团忽悠:互联网思维--TOMsInsight 2014.08.01
  4. App上架App Store
  5. 如何画一个系统的设计图
  6. 帮我用python写一个淘宝抢购的代码
  7. 【NPL】如何解决90%的自然语言处理问题:分步指南奉上
  8. Dynamics CRM: [问题已解决]Cannot open Sql Encryption Symmetric Key because Symmetric Key password...
  9. python测试脚本实例-使用python测试框架完成自动化测试并生成报告-实例练习
  10. 松翰SN8P2711-C替换料