• CRM(2)


    一:创建项目名称,并且配置好数据库

    二:数据模型场景

     1 设计模型类;
     2 # 模拟整个业务流程
     3     1.确认整个过程中所要涉及的角色:销售,学生,教师,管理员等;
     4         # Role;
     5     2.每个角色对应着多个用户,用户可能也对应多个角色,比如:教师也担任管理员的角色;
     6         # UserProfile(ManyToMany,Role);
     7     3.客户报名学习,需要填写客户信息;
     8         # CustomerInfo;
     9         # 需要填写的信息包括:
    10         # 姓名,联系方式,来源(转介绍,转介绍人),咨询人,客户状态,咨询时间;
    11     4.如果成功报名,需要录入学员表;
    12         # Students;
    13         # :需要填写学员名称(从客户表中取ForeignKey)
    14         # :需要填写所在班级(班级对应着课程信息,校区信息)
    15         # ClassInfo;<<--Course,Branch;
    16         # :班级类型,学期,任课教师(从用户中取),开班日期,毕业日期;
    17         # Course:课程名,学费,周期,大纲;
    18         # Branch:校区名,地址;
    19     5.如果没有报名,需要对这类客户做一个跟踪记录;
    20         # CustomerInfo;
    21         # 需要记录的信息包括:
    22         # 客户(客户表中取),跟踪信息,跟踪人(用户表中取),客户报名状态,填写时间;
    23     6.在课期间,需要有上课的记录,以及学员作业成绩/考勤等记录;
    24         # CourseRecord:上课记录
    25         # :所在班级(在班级表中取),课程节次,上课教师(用户表中取),本节主题,本节内容,是否有作业,作业需求,记录日期;
    26         # StudyRecord:学习记录
    27         # :课程,学员,分数等级,成绩备注,考勤状况,记录时间;
    数据模型场景

    三:设计数据库

      1 from django.db import models
      2 from django.contrib.auth.models import User   #使用Django内置的用户表
      3 
      4 # Create your models here.
      5 
      6 class UserProfile(models.Model):
      7     """
      8     用户信息表
      9     """
     10     user = models.OneToOneField(User,on_delete=models.CASCADE)  #创建外键,关联django用户表
     11     #扩展用户字段
     12     name = models.CharField(max_length=64,verbose_name="姓名")
     13     role = models.ManyToManyField("Role",blank=True)  # 双向一对多==多对多
     14 
     15     def __str__(self):  #__unicode__   python2.7版本
     16         return self.name
     17     class Meta:
     18         verbose_name_plural = "用户信息"
     19 
     20 class Role(models.Model):
     21     """
     22     角色表
     23     """
     24     name = models.CharField(max_length=64,unique=True)  # 角色名不可以重复
     25     menus = models.ManyToManyField("Menus",blank=True)
     26 
     27     def __str__(self):
     28         return self.name
     29     class Meta:
     30         verbose_name_plural = "角色"
     31 
     32 class Student(models.Model):
     33     """
     34     学员表
     35     """
     36     customer = models.ForeignKey("CustomerInfo",on_delete=models.CASCADE)
     37     class_grades = models.ManyToManyField("ClassList")
     38     def __str__(self):
     39         return self.customer
     40     class Meta:
     41         verbose_name = "学员表"
     42         verbose_name_plural = "学员表"
     43 
     44 class CustomerInfo(models.Model):
     45     """
     46     客户信息表
     47     """
     48     name = models.CharField(max_length=64,default=None)  # 首次报名可能不知道名字
     49     contact_type_choices = ((0,'qq'),
     50                             (1,'微信'),
     51                             (2,'手机号'),
     52                             )
     53     contact_type = models.SmallIntegerField(choices=contact_type_choices,default=0)
     54     contact = models.CharField(max_length=64,unique=True)
     55     source_choices = ((0,'QQ群'),
     56                       (1,'51CTO'),
     57                       (2,'百度推广'),
     58                       (3,'知乎'),
     59                       (4,'转介绍'),
     60                       (5,'其他'),
     61                       )
     62     source = models.SmallIntegerField(choices=source_choices)
     63     referral_from = models.ForeignKey("self",blank=True,null=True,verbose_name="转介绍",on_delete=models.CASCADE)
     64     consult_courses = models.ManyToManyField("Course",verbose_name="咨询课程")
     65     consult_content = models.TextField(verbose_name="咨询内容")
     66     status_choices = ((0,'未报名'),
     67                       (1,'已报名'),
     68                       (2,'已退学')
     69                       )
     70     status = models.SmallIntegerField(choices=status_choices)
     71     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE)
     72     date = models.DateField(auto_now_add=True)
     73 
     74     def __str__(self):
     75         return self.name
     76     class Meta:
     77         verbose_name = "客户表"
     78         verbose_name_plural = "客户表"
     79 
     80 class CustomerFollowUp(models.Model):
     81     """
     82     客户跟踪记录表
     83     """
     84     customer = models.ForeignKey("CustomerInfo",on_delete=models.CASCADE)
     85     content = models.TextField(verbose_name="跟踪内容")
     86     user = models.ForeignKey("UserProfile",verbose_name="跟进人",on_delete=models.CASCADE)
     87     status_choices = ((0,'近期无报名计划'),
     88                       (1, '一个月内报名'),
     89                       (2, '两周内报名'),
     90                       (3, '已报名'),
     91                      )
     92     status = models.SmallIntegerField(choices=status_choices)
     93     date = models.DateField(auto_now_add=True)
     94     def __str__(self):
     95         return self.content
     96     class Meta:
     97         verbose_name = "客户追踪"
     98         verbose_name_plural = "客户追踪"
     99 
    100 class Course(models.Model):
    101     """
    102     课程表
    103     """
    104     name = models.CharField(verbose_name='课程名称',max_length=64,unique=True)
    105     price = models.PositiveSmallIntegerField()
    106     period = models.PositiveSmallIntegerField(verbose_name="课程周期(月)",default=5)
    107     outline = models.TextField(verbose_name="大纲")
    108 
    109     def __str__(self):
    110         return self.name
    111     class Meta:
    112         verbose_name = "课程表"
    113         verbose_name_plural = "课程表"
    114 
    115 class ClassList(models.Model):
    116     """
    117     班级列表
    118     """
    119     branchschool = models.ForeignKey("BranchSchool",on_delete=models.CASCADE)
    120     course = models.ForeignKey("Course",on_delete=models.CASCADE)
    121     class_type_choices = ((0,'脱产'),
    122                           (1,'周末'),
    123                           (2,'网络班'),
    124                           )
    125     class_type = models.SmallIntegerField(choices=class_type_choices,default=0)
    126     semester = models.SmallIntegerField(verbose_name="学期")
    127     teachers = models.ManyToManyField("UserProfile",verbose_name="讲师")
    128     start_date = models.DateField("开班日期")
    129     graduate_date = models.DateField("毕业日期",blank=True,null=True)
    130 
    131     def __str__(self):
    132         return "%s(%s)期" %(self.course.name,self.semester)
    133 
    134     class Meta:
    135         """联合唯一"""
    136         unique_together = [
    137             ('branchschool','class_type','course','semester')
    138         ]
    139         verbose_name = "班级"
    140         verbose_name_plural = "班级"
    141 
    142 class CourseRecord(models.Model):
    143     """
    144     上课记录表
    145     """
    146     class_grade = models.ForeignKey("ClassList",verbose_name="上课班级",on_delete=models.CASCADE)
    147     day_num = models.PositiveSmallIntegerField(verbose_name="课程节次")
    148     teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)
    149     title = models.CharField("本节主题",max_length=64)
    150     content = models.TextField("本节内容")
    151     has_homework = models.BooleanField("本节有作业",default=True)
    152     homework = models.TextField("作业需求",blank=True,null=True)
    153     date = models.DateTimeField(auto_now_add=True)
    154 
    155     def __str__(self):
    156         return "%s第(%s)节" %(self.class_grade,self.day_num)
    157     class Meta:
    158         unique_together = [
    159             ('class_grade','day_num')
    160         ]
    161         verbose_name_plural = "上课记录"
    162 
    163 class StudyRecord(models.Model):
    164     """
    165     学习记录表
    166     """
    167     course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)
    168     student = models.ForeignKey("Student",on_delete=models.CASCADE)
    169     score_choices = ((100,"A+"),
    170                      (90,"A"),
    171                      (85,"B+"),
    172                      (80,"B"),
    173                      (75,"B-"),
    174                      (70,"C+"),
    175                      (60,"C"),
    176                      (40,"C-"),
    177                      (-50,"D"),
    178                      (0,"N/A"),   #not avaliable
    179                      (-100,"COPY"),  #not avaliable
    180                     )
    181     score = models.SmallIntegerField(choices=score_choices,default=0)
    182     show_choices = ((0,'缺勤'),
    183                     (1,'已迟到'),
    184                     (2,'迟到'),
    185                     (3,'早退'),
    186                     )
    187     show_status = models.SmallIntegerField(choices=show_choices,default=1)
    188     note = models.TextField("成绩备注",blank=True,null=True)
    189     date = models.DateTimeField(auto_now_add=True)
    190 
    191     def __str__(self):
    192         return "%s %s %s" %(self.course_record,self.student,self.score)
    193     class Meta:
    194         unique_together = ('course_record','student')
    195         verbose_name_plural = "学习记录"
    196 
    197 class BranchSchool(models.Model):
    198     """
    199     校区
    200     """
    201     name = models.CharField(max_length=64,unique=True)
    202     addr = models.CharField(max_length=128,blank=True,null=True)
    203     def __str__(self):
    204         return self.name
    205     class Meta:
    206         verbose_name = "校区"
    207         verbose_name_plural = "校区"
    208 
    209 class Menus(models.Model):
    210     """
    211     动态菜单
    212     """
    213     name = models.CharField(max_length=64)
    214     url_type_choices = ((0,'absolute'),
    215                         (1,'dynamic'),
    216                         )
    217     url_type = models.SmallIntegerField(choices=url_type_choices)
    218     url_name = models.CharField(max_length=128)
    219 
    220     def __str__(self):
    221         return self.name
    222     class Meat:
    223         unique_together = ('name','url_name')
    224         verbose_name_plural = "菜单栏"
    225 # 角色与菜单多对多关系,在Role表中添加关联
    model.py

    四:注册数据表

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

    五:生成数据表并创建管理员账户

    1 python manage.py makemigrations
    2 python manage.py migrate
    3 
    4 创建管理员用户
    5 
    6 python manage.py createsuperuser

    为啥我的后台页面和原生的admin后台管理页面不一样,因为我美化了后台只需要在settings做以下几步就可以搞定

     1 INSTALLED_APPS = [
     2     'suit',
     3     'django.contrib.admin',
     4     'django.contrib.auth',
     5     'django.contrib.contenttypes',
     6     'django.contrib.sessions',
     7     'django.contrib.messages',
     8     'django.contrib.staticfiles',
     9     'crm.apps.CrmConfig',
    10 ]
    11 
    12 
    13 
    14 LANGUAGE_CODE = 'zh-Hans'
    15 
    16 TIME_ZONE = 'Asia/Shanghai'
    17 
    18 USE_I18N = True
    19 
    20 USE_L10N = False
    21 
    22 USE_TZ = True
    23 
    24 DATETIME_FORMAT = 'Y-m-d H:i:s'
    25 DATE_FORMAT = 'Y-m-d'
    26 
    27 SUIT_CONFIG = {
    28     'ADMIN_NAME': 'CRM管理系统',
    29     'MENU': (
    30         'sites',
    31         {'app': 'accounts', 'label': '帐户'},
    32         {'app': 'zinnia', 'label': '博客'},
    33         {'app': 'auth', 'label': '认证管理'},
    34     ),
    35 }
    36 
    37 
    38 # Static files (CSS, JavaScript, Images)
    39 # https://docs.djangoproject.com/en/2.0/howto/static-files/
    40 
    41 STATIC_URL = '/static/'
    42 STATICFILES_DIRS = (
    43     os.path.join(BASE_DIR,'statics'),
    44 )
  • 相关阅读:
    localhost和127.0.0.1及ip区别
    Linux常用命令大全
    百度搜红包相关代码(1)
    今天开博第一篇,呵呵
    杯具啊,中考
    新年感想
    【转】汇编语言基础
    margin与padding
    .net 中的Literal Label 控件、Literal 控件、Panel 控件和 Placeholder 控件
    HTML 5 中的新元素
  • 原文地址:https://www.cnblogs.com/sun1994/p/8856692.html
Copyright © 2020-2023  润新知