CRM系统-----学员管理系统
1.需求分析
2.使用组件
django2.0+bootstrap3.37+jquery1.12+mysql8.0
django2.1:https://www.djangoproject.com/
3.表结构设计
models.py
![](/assets/blank.gif)
![](/assets/blank.gif)
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中添加一下代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
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
![](/assets/blank.gif)
![](/assets/blank.gif)
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
![](/assets/blank.gif)
![](/assets/blank.gif)
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
![](/assets/blank.gif)
![](/assets/blank.gif)
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文件中循环菜单
![](/assets/blank.gif)
![](/assets/blank.gif)
1 {% extends "index.html" %} 2 3 {% block page-content %} 4 客户库 5 {% endblock %}
customer
![](/assets/blank.gif)
![](/assets/blank.gif)
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系统-----学员管理系统相关推荐
- CRM系统-----学员管理系统---admin自定义开发3
admin的自定制开发 18.django实现自定义用户认证 1 from django.db import models 2 from django.contrib.auth.models impo ...
- CRM系统-----学员管理系统---admin自定义开发2
7.admin的自定制开发 10.实现与django admin filter_horizontal一样的复选框 实现效果: 首先要在king_admin中添加 filter_horizonta ...
- 客户关系管理系统 java_Java高级项目实战02:客户关系管理系统CRM系统模块分析与介绍...
先来CRM系统结构图: 每个模块作用介绍如下: 1.营销管理 营销机会管理:针对企业中客户的质询需求所建立的信息录入功能,方便销售人员进行后续的客户需求跟踪与联系,提高企业客户购买产品的几率. 营销开 ...
- 【分享】如何自动同步企业微信外部客户信息到CRM系统?
许多企业的销售人员利用企业微信添加外部客户,与客户沟通,但是销售添加外部客户后并不加外部客户录入到企业CRM中.另外,即便是录入了客户到企业CRM系统中,也经常不去更新外部联系人的信息变化到企业CRM ...
- 计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署
计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署 计算机毕业设计springboot驾校学员管理系统w42sj源码+系统+程序+lw文档+部署 本源码技术栈 ...
- crm系统是什么很棒ec实力_CRM系统都有哪些功能?CRM管理系统的主要用途又是什么?...
就目前市面上的CRM系统众多,各个供应商可能都是不太一样的,但是大致上还是离不开这几个功能:即营销自动化.客户管理.销售管理.客服你管理.报表分析等. 其中,销售自动化功能可以说是每个CRM系统的核心 ...
- C语言 项目 CRM系统(客户信息管理系统)
项目目标 项目需求说明 系统界面 1)添加客户界面 通过编号来区分客户 2)删除客户界面 对用户输入的编号进行核查,存在与否,合法与否 3)显示客户列表界面 4)修改客户信息的界面 项目设计 Cust ...
- python面相对象编程超市系统_python面向对象编程: 面向对象版学员管理系统
转载自https://www.cnblogs.com/LynHome/archive/2020/04/06/12650318.html 详细解读请参考https://www.cnblogs.com/b ...
- crm管理系统是什么意思 crm系统全称是什么 - whale帷幄
whale 帷幄营销云 「帷幄营销云」为品牌客户提供一站式的数字营销运营解决方案.它以行业最佳实践为基础,整合内容创意.营销玩法.人群智选.全域投放.营销 ROI 分析于一体:在满足市场营销人员对平台 ...
最新文章
- Linux中查看所有正在运行的进程
- centOS7 Minima无法上网解决方案(Linux设置开机自动获取ip地址)
- flask和ajax,Flask flash和url_用于AJAX
- 非公平锁和公平锁在reetrantlock里的实现过程是怎样的
- Sentinel(十四)之控制台
- 通过设计国际象棋游戏来了解策略模式
- facebook.com_如何降低电子商务的Facebook CPM
- 钱大妈关闭所有北京门店:低估了北京市场的难度
- 电池图标不见了怎么解决
- SparkContext详述
- 基于python车牌识别系统_GitHub - DataXujing/vehicle-license-plate-recognition: 基于Python的车牌检测和识别系统:...
- 与大数据同行—学习和教育的未来 - 电子书下载(高清版PDF格式+EPUB格式)
- 基于java+ssh+mysql实现的共享自行车单车租赁|出租管理系统项目源代码
- IntelliJ IDEA 2017 汉化包
- 数据表对应关系(一对一、一对多、多对多)
- vue3的逻辑复用抽离
- 百钱买小鸡/*公鸡5文钱1只,母鸡三文钱一只,小鸡一文钱三只。现在用100文钱共买了100只鸡,问这100只鸡中,公鸡,母鸡,小鸡各是多少只?
- 戴尔服务器r740硬盘指示灯,戴尔R740服务器获取cpu、内存、硬盘参数信息。
- 耳部穴位取穴 耳朵对应身体各部位反射图
- Google 应用与游戏出海 4 月刊: 带您连线 GDC,赢在发布前!
热门文章
- CSS 实现自动等分圆效果
- 微信服务器向公众号推送消息或事件后,微信服务器向公众号推送消息或事件后,得到的回应不合法?...
- 病毒性的抱团忽悠:互联网思维--TOMsInsight 2014.08.01
- App上架App Store
- 如何画一个系统的设计图
- 帮我用python写一个淘宝抢购的代码
- 【NPL】如何解决90%的自然语言处理问题:分步指南奉上
- Dynamics CRM: [问题已解决]Cannot open Sql Encryption Symmetric Key because Symmetric Key password...
- python测试脚本实例-使用python测试框架完成自动化测试并生成报告-实例练习
- 松翰SN8P2711-C替换料