Django项目:CRM(客户关系管理系统)--58--48PerfectCRM实现CRM客户报名流程学生合同
1 # sales_urls.py 2 # ————————47PerfectCRM实现CRM客户报名流程———————— 3 from django.conf.urls import url 4 from bpm.sales import sales_views 5 6 urlpatterns = [ 7 url(r'^customer/(\d+)/enrollment/$', sales_views.enrollment, name="enrollment"),#客户招生#报名流程一 下一步 8 9 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 10 url(r'^customer/registration/(\d+)/$', sales_views.stu_registration, name="stu_registration"), # 报名流程二 学员签同合 11 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 12 ] 13 # ————————47PerfectCRM实现CRM客户报名流程————————
1 # sales_views.py 2 # ————————47PerfectCRM实现CRM客户报名流程———————— 3 from django.db import IntegrityError #主动捕捉错误信息 4 from django.shortcuts import render #页面返回 5 from crm import models #数据库 6 from bpm.bpm_auxiliary import bpm_forms #自定制 forms 7 from django.contrib.auth.decorators import login_required# 登陆后页面才能访问 8 9 # ————————47PerfectCRM实现CRM客户报名流程———————— 10 from django.core.mail import send_mail 11 # send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们) 12 import random 13 import datetime # 获取时间#登陆过期 14 #发送邮件的功能 #验证码#密码 15 class stmp() : 16 def __init__(self): 17 self.emaillist=[] #发送给谁 18 self.code=None #验证码#密码 19 def stmps(self,request,email,msg_mail): #传参数#页面,session #邮箱,发送给谁 #内容 20 self.emaillist.append(email) #将邮箱地址添加到调用Django发送邮件功能 21 # ——————生成验证码—————— 22 _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z 23 _upper_cases = _letter_cases.upper() # 大写字母 24 _numbers = ''.join(map(str, range(3, 10))) # 数字 25 chars = ''.join((_letter_cases, _upper_cases, _numbers)) # 变成一条字符串 26 list = random.sample(chars, 4) # 从一条字符串随机选4个字符变成列表 27 self.code = ''.join(list) # 列表变字符串 28 # ——————生成验证码—————— 29 # ——————调用Django发送邮件—————— 30 title= 'PerfectCRM项目自动邮件:%s'%self.code # 邮件标题#防止一样的内容被邮箱屏蔽 31 send_mail(title, # 邮件标题 32 msg_mail, # 验证码内容 33 'perfectcrm@sina.cn', # 发送的邮箱 #根据情况重新配置 34 self.emaillist, # 接受的邮箱 35 fail_silently=False, # 静默,抛出异常 36 ) 37 print('发送邮件成功!没收到要换标题!检查发送邮箱的配置!') 38 # ——————调用Django发送邮件—————— 39 40 # ————————47PerfectCRM实现CRM客户报名流程———————— 41 # ————————47PerfectCRM实现CRM客户报名流程———————— 42 43 #报名填写 销售 44 @login_required # 登陆后页面才能访问 45 def enrollment(request,customer_id): 46 msgs={} #错误信息 47 customer_obj=models.Customer.objects.get(id=customer_id)#取到客户信息记录 #返回到页面#报名人 48 consultant_obj=models.UserProfile.objects.get(id=request.user.id)#报名课程顾问 49 50 stmp_mail = {} #邮件发送成功 51 stmpemail = stmp() #实例化发送邮件的功能 52 email = request.POST.get('email') # 让页面POST提交的值,在页面GET后仍然存在显示 53 if request.method=="POST": 54 enroll_form= bpm_forms.EnrollmentForm(request.POST)#获取数据 55 if enroll_form.is_valid():#表单验证 56 msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/" 57 try: 58 enroll_form.cleaned_data['customer']=customer_obj#添加学员对象 记录 #报名人 59 enroll_form.cleaned_data['consultant'] = consultant_obj#报名课程顾问 60 enroll_obj=models.Enrollment.objects.create(**enroll_form.cleaned_data)#创建记录 61 msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id 62 except IntegrityError as e: 63 #取到这条记录 64 enroll_obj=models.Enrollment.objects.get(customer_id=customer_obj.id, 65 enrolled_class_id=enroll_form.cleaned_data['enrolled_class'].id) 66 enroll_form.add_error('__all__','记录已经存在,不能重复创建!') 67 msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id 68 if email: 69 msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s/"%enroll_obj.id 70 stmpemail.stmps(request, email,msg_mail) # 发送邮件 71 stmp_mail['ok'] = "邮件已发送成功!" 72 73 else: 74 enroll_form= bpm_forms.EnrollmentForm()#modelform表单 75 return render(request, 'bpm_sales/enrollment.html', locals()) 76 # ————————47PerfectCRM实现CRM客户报名流程———————— 77 78 79 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 80 #学员合同签定 81 def stu_registration(request,enroll_id): 82 enroll_obj=models.Enrollment.objects.get(id=enroll_id)#获取报名记录 83 customer_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#生成表单 84 return render(request,'bpm_sales/stu_registration.html',locals()) 85 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
1 # forms.py 2 # ————————47PerfectCRM实现CRM客户报名流程———————— 3 from crm import models #数据库 4 from django.forms import ModelForm #继承forms自定制 5 #报名 销售填写 6 class EnrollmentForm(ModelForm): 7 def __new__(cls, *args, **kwargs): 8 for field_name,field_obj in cls.base_fields.items(): 9 field_obj.widget.attrs['class'] = 'form-control'## 前端的样式 10 return ModelForm.__new__(cls) 11 class Meta: 12 model= models.Enrollment 13 fields= ['enrolled_class'] 14 # ————————47PerfectCRM实现CRM客户报名流程———————— 15 16 17 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 18 #报名学员填 写 19 class CustomerForm(ModelForm): 20 def __new__(cls, *args, **kwargs): 21 for field_name,field_obj in cls.base_fields.items(): 22 field_obj.widget.attrs['class'] = 'form-control'## 前端的样式 23 if field_name in cls.Meta.readonly_fields:#如果不可修改 24 field_obj.widget.attrs['disabled'] = True## 前端的样式 灰色 25 return ModelForm.__new__(cls) 26 27 class Meta: 28 model=models.Customer#客户表 29 fields='__all__' 30 exclude=['tags','content','memo','status','referral_from','consult_courses']#排除,不显示 31 readonly_fields=['qq','consultant','source']#不可修改 32 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
1 {#stu_registration.html#} 2 {## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#} 3 {% extends 'bpm_master/bpm_sample.html' %} 4 {% load bpm_tags %} 5 {% block right-container-content %} {#自定义内容开始 右边页面内容#} 6 <div class="container col-lg-7 col-md-offset-2"> 7 <div class="panel panel-warning"> 8 <div class=" panel-heading"> 9 <h3 class="panel-title container">报名入学|信息填写</h3> 10 </div> 11 <div class="panel-body "> <!--返回提交函数--> 12 <form method="post" class="form-horizontal" role="form">{% csrf_token %} 13 {% for foo in customer_form %} 14 <div class="form-group"> 15 <label for="inputEmail3" class="col-sm-2 control-label">{{ foo.label }}</label> 16 <div class="col-sm-8"> 17 {{ foo }} 18 </div> 19 </div> 20 {% endfor %} 21 <hr> 22 {#返回06学员报名信息表的数据#} 23 <div class="form-group"> 24 <label for="inputEmail3" class="col-sm-2 control-label">所报班级</label> 25 <div class="col-sm-8"> 26 {{ enroll_obj.enrolled_class }} 27 </div> 28 </div> 29 <div class="form-group"> 30 <label for="inputEmail3" class="col-sm-2 control-label">课程费用</label> 31 <div class="col-sm-8"> 32 {{ enroll_obj.enrolled_class.course.price }} 33 </div> 34 </div> 35 <div class="form-group"> 36 <label for="inputEmail3" class="col-sm-2 control-label">开课日期</label> 37 <div class="col-sm-8"> 38 {{ enroll_obj.enrolled_class.start_date }} 39 </div> 40 </div> 41 42 <div class="form-group"> 43 <label for="inputEmail3" class="col-sm-2 control-label">合同</label> 44 <div class="col-sm-10"> 45 <div style="width: 550px"> 46 <pre style="height: 300px">{% render_enrolled_contract enroll_obj %} </pre> <!--tgs--> 47 </div> 48 49 </div> 50 </div> 51 <div class="form-group"> 52 <div class="col-sm-12"> 53 <input type="checkbox" value="{{ enroll_obj.contract_agreed }}" name="contract_agreed" 54 checked> 55 我已经认真阅读完协议并接受所有条款 56 </div> 57 </div> 58 <div class="text-center"> 59 <input type="submit" class="btn btn-info" value="提交"> 60 </div> 61 </form> 62 </div> 63 <div class="panel-footer"> 64 <input type="button" class="btn btn-danger right" value="关闭" onclick="CloseWebPage()"> 65 </div> 66 </div> 67 </div> 68 {% endblock %} 69 70 {% block js %} 71 <script> 72 function CloseWebPage() { 73 if (confirm("您确定要关闭本页吗?")) { 74 window.opener = null; 75 window.open('', '_self'); 76 window.close(); 77 } 78 else { 79 } 80 } 81 </script> 82 {% endblock %} 83 {## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
1 # bpm_tags.py 2 3 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 4 from django import template 5 register = template.Library() #模板库 6 7 #合同格式 8 @register.simple_tag 9 def render_enrolled_contract(enroll_obj):#合同格式 10 if enroll_obj.enrolled_class.contract.template: 11 return enroll_obj.enrolled_class.contract.template.format(course_name=enroll_obj.enrolled_class,stu_name=enroll_obj.customer.name) 12 else: 13 return '' 14 15 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 16 17 # bpm_tags.py
1 # settings.py 2 3 """ 4 Django settings for PerfectCRM project. 5 6 Generated by 'django-admin startproject' using Django 2.0.3. 7 8 For more information on this file, see 9 https://docs.djangoproject.com/en/2.0/topics/settings/ 10 11 For the full list of settings and their values, see 12 https://docs.djangoproject.com/en/2.0/ref/settings/ 13 """ 14 15 import os 16 17 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 18 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 19 20 21 # Quick-start development settings - unsuitable for production 22 # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ 23 24 # SECURITY WARNING: keep the secret key used in production secret! 25 SECRET_KEY = 'atkhzsd7emv4_okn@ynhji)p)qbpuvhq+a7@yx5=chaa0$l_br' 26 27 # SECURITY WARNING: don't run with debug turned on in production! 28 DEBUG = True 29 30 ALLOWED_HOSTS = [] 31 32 33 # Application definition 34 35 INSTALLED_APPS = [ 36 'django.contrib.admin', 37 'django.contrib.auth', 38 'django.contrib.contenttypes', 39 'django.contrib.sessions', 40 'django.contrib.messages', 41 'django.contrib.staticfiles', 42 43 # ————————04PerfectCRM实现King_admin注册功能———————— 44 # 'crm.apps.CrmConfig', 45 'crm', 46 # ————————04PerfectCRM实现King_admin注册功能———————— 47 48 # ————————02PerfectCRM创建ADMIN页面———————— 49 'king_admin', 50 # ————————02PerfectCRM创建ADMIN页面———————— 51 # ————————38PerfectCRM实现全局账号登录注销———————— 52 'gbacc', 53 # ————————38PerfectCRM实现全局账号登录注销———————— 54 55 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 56 'bpm', 57 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 58 ] 59 60 MIDDLEWARE = [ 61 'django.middleware.security.SecurityMiddleware', 62 'django.contrib.sessions.middleware.SessionMiddleware', 63 'django.middleware.common.CommonMiddleware', 64 'django.middleware.csrf.CsrfViewMiddleware', 65 'django.contrib.auth.middleware.AuthenticationMiddleware', 66 'django.contrib.messages.middleware.MessageMiddleware', 67 'django.middleware.clickjacking.XFrameOptionsMiddleware', 68 ] 69 70 ROOT_URLCONF = 'PerfectCRM.urls' 71 72 TEMPLATES = [ 73 { 74 'BACKEND': 'django.template.backends.django.DjangoTemplates', 75 # ————————02PerfectCRM创建ADMIN页面———————— 76 'DIRS': [os.path.join(BASE_DIR, 'templates'), 77 os.path.join(BASE_DIR, 'king_admin/king_templates'), 78 79 # ————————03PerfectCRM创建基本数据———————— 80 os.path.join(BASE_DIR, 'DBadd/DBadd_templates'), 81 # ————————03PerfectCRM创建基本数据———————— 82 # ————————38PerfectCRM实现全局账号登录注销———————— 83 os.path.join(BASE_DIR, 'gbacc/gbacc_templates'), 84 # ————————38PerfectCRM实现全局账号登录注销———————— 85 86 # ————————47PerfectCRM实现CRM客户报名流程———————— 87 os.path.join(BASE_DIR, 'bpm/bpm_templates'), ] 88 # ————————47PerfectCRM实现CRM客户报名流程———————— 89 90 , 91 # ————————02PerfectCRM创建ADMIN页面———————— 92 'APP_DIRS': True, 93 'OPTIONS': { 94 'context_processors': [ 95 'django.template.context_processors.debug', 96 'django.template.context_processors.request', 97 'django.contrib.auth.context_processors.auth', 98 'django.contrib.messages.context_processors.messages', 99 ], 100 }, 101 }, 102 ] 103 104 WSGI_APPLICATION = 'PerfectCRM.wsgi.application' 105 106 107 # Database 108 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases 109 110 DATABASES = { 111 'default': { 112 'ENGINE': 'django.db.backends.sqlite3', 113 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 114 } 115 } 116 117 118 # Password validation 119 # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators 120 121 AUTH_PASSWORD_VALIDATORS = [ 122 { 123 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 124 }, 125 { 126 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 127 }, 128 { 129 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 130 }, 131 { 132 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 133 }, 134 ] 135 136 137 # Internationalization 138 # https://docs.djangoproject.com/en/2.0/topics/i18n/ 139 140 # ————————01PerfectCRM基本配置ADMIN———————— 141 #LANGUAGE_CODE = 'en-us' 142 143 #英文转中文方法 144 LANGUAGE_CODE = 'zh-Hans' 145 # ————————01PerfectCRM基本配置ADMIN———————— 146 147 TIME_ZONE = 'UTC' 148 149 USE_I18N = True 150 151 USE_L10N = True 152 153 USE_TZ = True 154 155 156 # Static files (CSS, JavaScript, Images) 157 # https://docs.djangoproject.com/en/2.0/howto/static-files/ 158 159 STATIC_URL = '/static/' 160 161 # ————————01PerfectCRM基本配置ADMIN———————— 162 STATICFILES_DIRS = [os.path.join(BASE_DIR,'king_admin/static'), 163 # ————————01PerfectCRM基本配置ADMIN———————— 164 # ————————38PerfectCRM实现全局账号登录注销———————— 165 os.path.join(BASE_DIR, 'gbacc/static'), 166 # ————————38PerfectCRM实现全局账号登录注销———————— 167 168 # ————————47PerfectCRM实现CRM客户报名流程———————— 169 os.path.join(BASE_DIR, 'bpm/static'),] 170 # ————————47PerfectCRM实现CRM客户报名流程———————— 171 172 173 # ————————34PerfectCRM实现CRM自定义用户———————— 174 AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 175 # ————————34PerfectCRM实现CRM自定义用户———————— 176 177 178 179 # ————————44PerfectCRM实现账号快速注册登陆———————— 180 # send e-mail 181 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #email后端 182 EMAIL_USE_TLS = False #是否使用TLS安全传输协议 183 EMAIL_USE_SSL = True #是否使用SSL加密,qq企业邮箱要求使用 184 EMAIL_HOST = 'smtp.sina.cn' #发送邮件的邮箱 的 SMTP服务器 #根据情况重新配置 185 EMAIL_PORT = 465 #发件箱的SMTP服务器端口 #一般不需要修改465 186 EMAIL_HOST_USER = 'perfectcrm@sina.cn' #发送邮件的邮箱账号 #根据情况重新配置 #perfectcrm@sina.cn pydjango@sina.cn 187 EMAIL_HOST_PASSWORD = 'admin123456' #发送邮件的邮箱密码 #根据情况重新配置 188 189 # ————————44PerfectCRM实现账号快速注册登陆———————— 190 191 192 # ————————46PerfectCRM实现登陆后页面才能访问———————— 193 LOGIN_URL = '/gbacc/gbacc_login/'# login_url 配置 #默认 /accounts/login/ #注意: / (绝对路径) 194 # ————————46PerfectCRM实现登陆后页面才能访问————————
1 #models.py 2 3 # ————————01PerfectCRM基本配置ADMIN———————— 4 5 from django.db import models 6 # Create your models here. 7 8 """ 9 #运行 Terminal 10 # 生成 数据表 11 # python manage.py makemigrations 12 # 数据表 迁移 13 # python manage.py migrate 14 """ 15 16 """01校区表""" 17 class Branch(models.Model): 18 name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型 19 addr = models.CharField(max_length=128) #地址 20 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 21 return self.name #返回 #校区名 22 class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据 23 verbose_name_plural = "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字 24 25 """02班级表""" 26 class ClassList(models.Model): 27 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 28 branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区 关联到 校区表 29 course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程 关联到 课程表 30 31 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 32 contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE) # 合同表 33 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 34 35 class_type_choices = ( #上课形式 36 (0,'面授(脱产)'), 37 (1,'面授(周末)'), 38 (2,'网络班'),) 39 #PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 40 class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式 41 42 #PositiveSmallIntegerField正小整数 0 ~ 32767 43 semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期 44 45 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。 46 teachers = models.ManyToManyField("UserProfile") # 老师 关联到 账号表 47 48 start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 49 50 # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空 51 end_date = models.DateField(verbose_name="结业日期",blank=True,null=True) 52 53 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 54 return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期 55 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 56 unique_together=('branch','course','semester') #联合索引 57 verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字 58 59 """03课程表,可以报名那些课程""" 60 class Course(models.Model): 61 name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型 62 price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767 63 period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767 64 outline = models.TextField() #课程大纲 #文本类型 65 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 66 return self.name #返回 #课程名 67 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 68 verbose_name_plural = "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字 69 70 '''04客户信息表''' 71 class Customer(models.Model): 72 name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空 73 qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复 74 qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空 75 phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空 76 77 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 78 id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号 79 email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email 80 sex_choices=((0,'保密'),(1,'男'),(2,'女')) 81 sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别') 82 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 83 84 85 source_choices = ( #客户渠道来源 (内存生成) 86 (0,'转介绍'), 87 (1,'QQ群'), 88 (2,'官网'), 89 (3,'百度推广'), 90 (4,'51CTO'), 91 (5,'知乎'), 92 (6,'市场推广'),) 93 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 94 source = models.SmallIntegerField(choices=source_choices)#客户渠道来源 95 96 #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空 97 referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的 98 99 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 100 consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表 101 102 content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 103 104 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。 105 tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表 106 107 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 108 consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 109 110 memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空 111 112 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 113 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 114 115 def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 116 return self.qq #返回 #QQ号 117 118 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 119 verbose_name_plural = "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字 120 121 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 122 #合同模版 123 class ContractTemplate(models.Model): 124 name=models.CharField('合同名称',max_length=64,unique=True) 125 template=models.TextField() 126 127 def __str__(self): 128 return self.name 129 class Meta: 130 verbose_name_plural='合同表' 131 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 132 133 134 """05客户跟进表""" 135 class CustomerFollowUp(models.Model): 136 137 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 138 customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到 客户信息表 139 140 content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 141 142 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 143 consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 144 145 intention_choices =( #报名状态 146 (0,'2周内报名'), 147 (1,'1个月内报名'), 148 (2,'近期无报名计划'), 149 (3,'已在其它机构报名'), 150 (4,'已报名'), 151 (5,'已拉黑'),) 152 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 153 intention=models.SmallIntegerField(choices=intention_choices) #报名状态 154 155 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 156 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 157 158 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 159 return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态 160 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 161 verbose_name_plural = "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字 162 163 """06学员报名信息表""" 164 class Enrollment(models.Model): 165 # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 166 customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到 客户信息表 167 enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到 班级表 168 consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到 账号表 169 170 #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称 171 contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同 172 contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核 173 174 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 175 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 176 177 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 178 return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级 179 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 180 unique_together = ("customer","enrolled_class")#联合索引 181 verbose_name_plural = "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字 182 183 """07缴费记录表""" 184 class Payment(models.Model): 185 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 186 customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 关联到 客户信息表 187 course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到 课程表 188 189 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500 190 amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额 191 192 #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 193 consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到 账号表 194 195 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 196 date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 197 198 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 199 return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额 200 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 201 verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字 202 203 """08每节课上课纪录表""" 204 class CourseRecord(models.Model): 205 # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 206 from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级 207 208 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称 209 day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课 210 211 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 212 teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁 关联到 账号表 213 214 #BooleanField布尔值类型#default=True默认(True)不允许出现空字符 215 has_homework = models.BooleanField(default=True) #有没有作业 216 217 # CharField定长文本#名字最长128#Django可空#数据库可以为空 218 homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题 219 220 #TextField无限制长度的文本#Django可空#数据库可以为空 221 homework_content = models.TextField(blank=True,null=True) #作业内容 222 223 #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 224 outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么 225 226 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 227 date = models.DateField(auto_now_add=True)#创建时间(数据库自增) 228 229 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 230 return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天) 231 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 232 unique_together = ("from_class","day_num") #联合索引 233 verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字 234 235 """09学习纪录""" 236 class StudyRecord(models.Model): 237 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 238 student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字 关联到 学员报名信息表 239 course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录 # 关联到 每节课上课纪录表 240 241 attendance_choices = (# 本节课上课状态记录 242 (0,"已签到"), 243 (1,"迟到"), 244 (2,"缺勤"), 245 (3,"早退"),) 246 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 247 attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录 248 249 score_choices = (#学习成绩 250 (100,"A+"), 251 (90,"A"), 252 (85,"B+"), 253 (80,"B"), 254 (75,"B-"), 255 (70,"C+"), 256 (65,"C"), 257 (40,"C-"), 258 (-20,"D"), 259 (-50,"COPY"), 260 (0,"N/A"),) 261 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 262 score = models.SmallIntegerField(choices=score_choices) #学习成绩 263 264 memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空 265 266 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 267 date = models.DateField(auto_now_add=True)#创建时间(数据库自增) 268 269 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 270 return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩 271 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 272 unique_together = ('student','course_record')#联合索引#学生名字#开课记录 273 verbose_name_plural = "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字 274 275 # ————————34PerfectCRM实现CRM自定义用户———————— 276 # """10账号表""" 277 # class UserProfile(models.Model): 278 # from django.contrib.auth.models import User # 使用django内置的用户表 279 # 280 # #OneToOneField一对一 #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 281 # user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表 282 # 283 # name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本 284 # 285 # #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空 286 # roles = models.ManyToManyField("Role",blank=True) #角色(权限) # 双向一对多==多对多 287 # 288 # def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 289 # return self.name #返回 #账号名 290 # class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据 291 # verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字 292 # ————————34PerfectCRM实现CRM自定义用户———————— 293 294 # ————————34PerfectCRM实现CRM自定义用户———————— 295 #10账号表,创建用户和超级用户 296 from django.contrib.auth.models import BaseUserManager 297 class UserProfileManager(BaseUserManager): 298 def create_user(self, email, name, password=None): 299 """ 300 创建并保存一个用户用给定的邮件,日期 301 出生和密码。 302 """ 303 if not email:#没有email 报错 304 raise ValueError('用户必须有一个电子邮件地址') 305 306 user = self.model( 307 email=self.normalize_email(email),#验证邮箱格式 308 name=name, 309 ) 310 user.set_password(password)#加密 311 user.is_active = True 312 user.save(using=self._db) 313 return user 314 def create_superuser(self, email, name, password): 315 """ 316 创建并保存一个超级用户具有给定邮件,日期 317 出生和密码。 318 """ 319 user = self.create_user(email, 320 password=password, 321 name=name 322 ) 323 user.is_active = True 324 user.is_superuser = True 325 user.save(using=self._db) 326 return user 327 328 """10账号表""" 329 """ 330 331 #删除数据库 332 333 #调用objects = UserProfileManager()#创建账号 #关联这个函数 334 335 #运行 Terminal 336 # 生成 数据表 337 # python manage.py makemigrations 338 # 数据表 迁移 339 # python manage.py migrate 340 Django Admin里账号密码重置方法 341 #运行 Terminal 342 python manage.py createsuperuser 343 344 Email address: admin@qq.com 345 用户名 : admin 346 Password: admin123456 347 Password (again): admin123456 348 """ 349 from django.contrib.auth.models import AbstractBaseUser 350 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 351 from django.utils.translation import ugettext_lazy as _ # 语言国际化 352 from django.utils.safestring import mark_safe 353 from django.contrib.auth.models import PermissionsMixin 354 # class UserProfile(AbstractBaseUser): 355 class UserProfile(AbstractBaseUser,PermissionsMixin): 356 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 357 email=models.EmailField( 358 verbose_name='邮箱账号', 359 max_length=255, 360 unique=True#唯一 #登陆账号 361 ) 362 name=models.CharField(max_length=32,verbose_name='用户名') 363 364 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 365 password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密码</a>''')) 366 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 367 368 is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号 369 is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号 370 objects = UserProfileManager()#创建账号 #关联这个函数 371 USERNAME_FIELD ='email'#指定做为 #登陆账号 372 REQUIRED_FIELDS = ['name']#必填字段 373 def get_full_name(self): 374 return self.email 375 def get_short_name(self): 376 #用户确认的电子邮件地址 377 return self.email 378 def __str__(self): 379 return self.name 380 def has_perm(self,perm,obj=None): 381 #指明用户是否被认为活跃的。以反选代替删除帐号。 382 #最简单的可能的答案:是的,总是 383 return True #有效 账号 384 def has_module_perms(self, app_label): 385 #指明用户是否可以登录到这个管理站点。 386 # 最简单的可能的答案:是的,总是 387 return True #职员状态 388 @property 389 def is_staff(self): 390 '''“用户的员工吗?”''' 391 #最简单的可能的答案:所有管理员都是员工 392 return self.is_superuser#是不是超级用户状态 393 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 #settings.py 394 # ————————34PerfectCRM实现CRM自定义用户———————— 395 396 """11角色表""" 397 class Role(models.Model): 398 name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节 399 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 400 return self.name#返回 #角色名 401 class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据 402 verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字 403 404 """12标签表""" 405 class Tag(models.Model): 406 name = models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复 407 def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 408 return self.name #返回 #标签名 409 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 410 verbose_name_plural = "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字 411 412 # ————————01PerfectCRM基本配置ADMIN————————
1 #admin.py 2 # ————————01PerfectCRM基本配置ADMIN———————— 3 from django.contrib import admin 4 # Register your models here. 5 from crm import models #从crm导入models 6 7 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 8 from django.shortcuts import render 9 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 10 11 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 12 from django import forms 13 from django.contrib.auth.admin import UserAdmin 14 from django.contrib.auth.forms import ReadOnlyPasswordHashField 15 from crm.models import UserProfile 16 #重写admin 17 class UserCreationForm(forms.ModelForm): 18 """ 一个表单来创建新用户。包括所有必需的 19 字段,加上重复密码。""" 20 password1 = forms.CharField(label='Password', widget=forms.PasswordInput) 21 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) 22 class Meta: 23 model = UserProfile 24 fields = ('email', 'name') 25 def clean_password2(self): 26 # 检查两个密码条目匹配 27 password1 = self.cleaned_data.get("password1") 28 password2 = self.cleaned_data.get("password2") 29 if password1 and password2 and password1 != password2: 30 raise forms.ValidationError("密码不匹配") 31 return password2 32 def save(self, commit=True): 33 #保存密码散列的格式提供 34 user = super(UserCreationForm, self).save(commit=False) 35 user.set_password(self.cleaned_data["password1"]) 36 if commit: 37 user.save() 38 return user 39 #重写admin 40 class UserChangeForm(forms.ModelForm): 41 """更新用户的一种形式。包括所有字段 42 用户,但取代了管理员的密码字段 43 密码散列显示领域。 44 """ 45 password = ReadOnlyPasswordHashField(label="Password", 46 help_text=("原始密码不存储,所以没有办法看到" 47 "这个用户的密码,但是你可以改变密码 " 48 "使用 <a href=\"../password/\">修改密码</a>."))#哈值 49 class Meta: 50 model = UserProfile 51 fields = ('email', 'password', 'name', 'is_active', 'is_superuser') 52 def clean_password(self): 53 # 不管用户提供什么,返回初始值。 54 # 这是在这里,而不是在球场上,因为 55 # 字段没有对初始值的访问 56 return self.initial["password"] 57 #重写admin 58 class UserProfileAdmin(UserAdmin):#用户类,继承上一个类 UserAdmin 59 # 单添加和更改用户实例 60 form = UserChangeForm 61 add_form = UserCreationForm 62 63 # 字段用于显示用户模型。 64 # 这些覆盖定义UserAdmin固定在底座上 65 # auth.User引用特定字段。 66 list_display = ('email', 'name','is_active', 'is_superuser', ) #显示字段表头 67 list_filter = ('is_superuser',) # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 68 fieldsets = ( #自定义显示字段 69 (None, {'fields': ('email','name', 'password')}), 70 ('个人信息', {'fields': ( 'email','name')}), 71 ('用户权限', {'fields': ('is_active','is_superuser','groups','user_permissions')}),#后台显示配置 72 ) 73 #添加自定义字段 74 # 覆盖get_fieldsets时使用这个属性创建一个用户。 75 add_fieldsets = ( 76 (None, { 77 'classes': ('wide',), 78 'fields': ('email', 'name', 'password1', 'password2')} 79 ), 80 ) 81 search_fields = ('email',) #搜索(不能包含CharField)(注意加 逗号 , ) 82 ordering = ('email',) #自定义排序,默认'-id' 83 filter_horizontal = ('groups','user_permissions', ) #复选框 84 85 # 现在注册这个新UserAdmin ,因为我们不在使用Django的内置权限 86 admin.site.register(UserProfile, UserProfileAdmin) 87 #注销 原来的 # admin.site.register(models.UserProfile) #10账号表 88 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 89 90 # ————————04PerfectCRM实现King_admin注册功能———————— 91 class CustomerAdmin(admin.ModelAdmin):#定制Djanago admin 92 list_display = ('id','qq','source','consultant','content','date')#显示字段表头 93 # ————————11PerfectCRM实现King_admin分页显示条数———————— 94 list_per_page = 2 #分页条数 95 # ————————11PerfectCRM实现King_admin分页显示条数———————— 96 # ————————16PerfectCRM实现King_admin日期过滤———————— 97 # ————————15PerfectCRM实现King_admin多条件过滤———————— 98 # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 99 # list_filter = ('source','consultant','consult_courses',) 100 list_filter = ('date','source','consultant','consult_courses',) 101 # ————————15PerfectCRM实现King_admin多条件过滤———————— 102 # ————————16PerfectCRM实现King_admin日期过滤———————— 103 # ————————18PerfectCRM实现King_admin搜索关键字———————— 104 #搜索(不能包含CharField)(注意加 逗号 , ) 105 search_fields = ('name','qq',) 106 # ————————18PerfectCRM实现King_admin搜索关键字———————— 107 108 # ————————26PerfectCRM实现King_admin自定义排序———————— 109 ordering = ['-qq'] #自定义排序,默认'-id' 110 # ————————26PerfectCRM实现King_admin自定义排序———————— 111 112 # ————————27PerfectCRM实现King_admin编辑复选框———————— 113 filter_horizontal = ('tags',) #复选框 114 # ————————27PerfectCRM实现King_admin编辑复选框———————— 115 116 # ————————28PerfectCRM实现King_admin编辑限制———————— 117 readonly_fields = ('qq','consultant',) # 不可修改 118 # ————————28PerfectCRM实现King_admin编辑限制———————— 119 120 121 122 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 123 # from django.shortcuts import render 124 actions = ['test_actions',]#定制功能 #测试返回到一个新页面 125 def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容 126 return render(request,"king_admin/table_index.html") 127 test_actions.short_description = "测试显示中文" 128 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 129 # ————————04PerfectCRM实现King_admin注册功能———————— 130 131 #注册到 Django Admin里 132 admin.site.register(models.Branch) #01校区表 133 admin.site.register(models.ClassList) #02班级表 134 admin.site.register(models.Course) #03课程表,可以报名那些课程 135 136 # ————————04PerfectCRM实现King_admin注册功能———————— 137 # admin.site.register(models.Customer) #04客户信息表 138 admin.site.register(models.Customer,CustomerAdmin) #04客户信息表 139 # ————————04PerfectCRM实现King_admin注册功能———————— 140 141 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 142 admin.site.register(models.ContractTemplate) #合同模版 143 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 144 145 146 147 admin.site.register(models.CustomerFollowUp) #05客户跟进表 148 admin.site.register(models.Enrollment) #06学员报名信息表 149 admin.site.register(models.Payment) #07缴费记录表 150 admin.site.register(models.CourseRecord) #08每节课上课纪录表 151 admin.site.register(models.StudyRecord) #09学习纪录 152 153 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 154 # admin.site.register(models.UserProfile) #10账号表 155 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 156 157 admin.site.register(models.Role) #11角色表 158 admin.site.register(models.Tag) #12标签表 159 160 ''' 161 Django Admin里账号密码重置方法 162 #运行 Terminal 163 164 python manage.py createsuperuser 165 166 Username : admin 167 Email address: admin@qq.com 168 Password: admin123456 169 Password (again): admin123456 170 171 172 英文转中文方法 173 到settings.py里修改 174 # LANGUAGE_CODE = 'en-us' 175 LANGUAGE_CODE = 'zh-Hans' 176 ''' 177 178 # ————————01PerfectCRM基本配置ADMIN————————
#运行 Terminal
# 生成 数据表
# python manage.py makemigrations
# 数据表 迁移
# python manage.py migrate
1 # DBadd_urls.py 2 # ————————03PerfectCRM创建基本数据———————— 3 from django.conf.urls import url 4 from DBadd import auth_views 5 from DBadd import crm_views 6 7 urlpatterns = [ 8 url(r'^auth_user/$', auth_views.auth_user), #Django账号表 9 10 url(r'^crm_Role/$', crm_views.crm_Role), #角色表 等基本信息 11 url(r'^crm_UserProfile/$', crm_views.crm_UserProfile),#账号表 #随机学生 12 url(r'^crm_userprofile_roles/$', crm_views.crm_userprofile_roles),#账号角色关联表 #随机学生 13 14 url(r'^crm_Customer/$', crm_views.crm_Customer), # 04客户信息表 15 16 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 17 url(r'^crm_ContractTemplate/$', crm_views.crm_ContractTemplate), # 角色表 等基本信息 18 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 19 ] 20 # ————————03PerfectCRM创建基本数据————————
1 # crm_views.py 2 3 # ————————03PerfectCRM创建基本数据———————— 4 5 from django.shortcuts import render 6 from django.shortcuts import redirect 7 from django.shortcuts import HttpResponse 8 9 10 from crm import models 11 from django.contrib.auth import models as auth_models 12 13 #随机字符串 14 import random 15 from random import choice 16 17 #添加"""基本数据""" 18 def crm_Role(request): 19 if request.method == "GET": 20 user_list = models.Role.objects.all() 21 return render(request, 'crm_Role.html', {'user_list':user_list}) 22 elif request.method == "POST": 23 try: 24 models.Role.objects.create(name='角色学生') 25 models.Role.objects.create(name='角色销售') 26 models.Role.objects.create(name='角色老师') 27 models.Role.objects.create(name='角色校长') 28 models.Role.objects.create(name='角色系统维护') 29 30 models.Branch.objects.create(name='北京校区',addr='北京天安门') 31 models.Branch.objects.create(name='广东校区',addr='广东东莞市') 32 models.Branch.objects.create(name='上海校区',addr='上海黄浦江') 33 models.Branch.objects.create(name='福建校区',addr='福建仙游县') 34 models.Branch.objects.create(name='四川校区',addr='四川成都市') 35 36 models.Tag.objects.create(name='好,很好') 37 models.Tag.objects.create(name='很有兴趣') 38 models.Tag.objects.create(name='兴趣不大') 39 models.Tag.objects.create(name='交钱很爽快') 40 models.Tag.objects.create(name='随便问问的') 41 42 models.Course.objects.create(name='Pyton',price='6666',period='40',outline='Python , 是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继JAVA,C++之后的的第三大语言。 特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性、可嵌入型、丰富的库、规范的代码等。') 43 models.Course.objects.create(name='PHP',price='8888',period='50',outline='PHP语言是目前Web后端开发使用最广泛的语言,几乎绝大多数网站使用。PHP开发快速,开发成本低,周期短,后期维护费用低,开源产品丰富。') 44 models.Course.objects.create(name='Java',price='9999',period='60',outline='完成本套餐的学习,学员可以全面掌握后续JavaEE开发所需的Java技术,为后续学习JavaEE开发打下坚实的基础。') 45 46 # ————————47PerfectCRM实现CRM客户报名流程———————— 47 48 # models.UserProfile.objects.create(name='ADMIN系统维护', user_id=1) 49 # models.UserProfile.objects.create(name='李白销售老师', user_id=2) 50 # models.UserProfile.objects.create(name='杜甫销售老师', user_id=3) 51 # models.UserProfile.objects.create(name='唐伯虎销售老师', user_id=4) 52 # models.UserProfile.objects.create(name='颜真卿老师', user_id=5) 53 # models.UserProfile.objects.create(name='罗贯中老师', user_id=6) 54 # models.UserProfile.objects.create(name='白居易老师', user_id=7) 55 # models.UserProfile.objects.create(name='施耐庵老师', user_id=8) 56 # models.UserProfile.objects.create(name='曹雪芹校长', user_id=9) 57 58 59 models.UserProfile.objects.create(last_login='2018-04-18', email='admin@qq.com',name='admin',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 60 models.UserProfile.objects.create(last_login='2018-04-18', email='admin1@qq.com',name='admin1',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 61 models.UserProfile.objects.create(last_login='2018-04-18', email='admin2@qq.com',name='admin2',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 62 models.UserProfile.objects.create(last_login='2018-04-18', email='admin3@qq.com',name='admin3',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 63 models.UserProfile.objects.create(last_login='2018-04-18', email='admin4@qq.com',name='admin4',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 64 models.UserProfile.objects.create(last_login='2018-04-18', email='admin5@qq.com',name='admin5',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 65 models.UserProfile.objects.create(last_login='2018-04-18', email='admin6@qq.com',name='admin6',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 66 models.UserProfile.objects.create(last_login='2018-04-18', email='admin7@qq.com',name='admin7',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 67 models.UserProfile.objects.create(last_login='2018-04-18', email='admin8@qq.com',name='admin8',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 68 models.UserProfile.objects.create(last_login='2018-04-18', email='admin9@qq.com',name='admin9',is_active=1,is_superuser=1,password='pbkdf2_sha256$100000$cCkwdwzBiea6$VNOFkD7HAKwsjKXsDZMOGO8ct3EpVMaX2JPU+h5PK9E=') 69 # ————————47PerfectCRM实现CRM客户报名流程———————— 70 71 models.ClassList.objects.create(class_type=1,semester=2,start_date='2018-03-20',branch_id=1,course_id=1) 72 models.ClassList.objects.create(class_type=0,semester=5,start_date='2018-03-20',branch_id=1,course_id=1) 73 models.ClassList.objects.create(class_type=2,semester=8,start_date='2018-03-20',branch_id=1,course_id=1) 74 models.ClassList.objects.create(class_type=0,semester=1,start_date='2018-03-20',branch_id=1,course_id=1) 75 models.ClassList.objects.create(class_type=1,semester=3,start_date='2018-03-20',branch_id=1,course_id=1) 76 models.ClassList.objects.create(class_type=0,semester=9,start_date='2018-03-20',branch_id=1,course_id=1) 77 models.ClassList.objects.create(class_type=2,semester=6,start_date='2018-03-20',branch_id=1,course_id=1) 78 models.ClassList.objects.create(class_type=1,semester=20,start_date='2018-03-20',branch_id=1,course_id=1) 79 models.ClassList.objects.create(class_type=0,semester=32,start_date='2018-03-20',branch_id=1,course_id=1) 80 81 82 except: 83 return HttpResponse('基本数据已经添加了。。。') 84 85 return redirect('/DBadd/crm_Role/') 86 87 88 89 #添加"""10账号表""" #随机学生 90 def crm_UserProfile(request): 91 if request.method == "GET": 92 user_list = models.UserProfile.objects.all() 93 return render(request, 'crm_UserProfile.html', {'user_list':user_list}) 94 elif request.method == "POST": 95 for i in range(50): 96 97 Rword = ''.join(''.join([chr(random.randint(0x4E00, 0x9FBF)) for i in range(3)]).split())# 随机中文 98 n=Rword 99 100 101 a = models.UserProfile.objects.values("user_id").all() 102 e = auth_models.User.objects.values("id").all() 103 print('eeeee', e, type(e)) 104 x=e.difference(a) 105 # for i in x: 106 # print('zzz', x, type(x)) 107 108 l=[] 109 for i in x: 110 l.append(i['id']) 111 print('llll', l, type(l)) 112 113 if len(l)==0: 114 return HttpResponse('请添加 admin的用户后,再来添加。。。') 115 else: 116 c = choice(l) 117 u = c 118 models.UserProfile.objects.create(name=n, user_id=u) 119 return redirect('/DBadd/crm_UserProfile/') 120 121 #添加"""10账号表--11角色表""" #随机学生 122 def crm_userprofile_roles(request): 123 if request.method == "GET": 124 user_list = models.UserProfile.objects.all() 125 role_list = models.Role.objects.get(id=1) 126 return render(request, 'crm_userprofile_roles.html', {'user_list':user_list,'role_list':role_list}) 127 elif request.method == "POST": 128 try: 129 for i in range(50): 130 b1 = models.Role.objects.get(id=1) 131 a=b1.userprofile_set.values("id").all() 132 133 e = models.UserProfile.objects.values("id").all() 134 x = e.difference(a) 135 136 l = [] 137 for i in x: 138 l.append(i['id']) 139 print('llll', l, type(l)) 140 141 if len(l) == 0: 142 return HttpResponse('请添加 数据 后,再来添加。。。') 143 else: 144 c = choice(l) 145 print('c', c, type(c)) 146 147 g1 = models.UserProfile.objects.get(id=c) 148 b1 = models.Role.objects.get(id=1) 149 g1.roles.add(b1) 150 return redirect('/DBadd/crm_userprofile_roles/') 151 except: 152 return HttpResponse('没有数据了。。。') 153 154 155 156 157 # 添加"""04客户信息表""" 158 def crm_Customer(request): 159 if request.method == "GET": 160 user_list = models.Customer.objects.all() 161 return render(request, 'crm_Customer.html', {'user_list': user_list}) 162 elif request.method == "POST": 163 for i in range(50): 164 Rword = ''.join(''.join([chr(random.randint(0x4E00, 0x9FBF)) for i in range(3)]).split()) # 随机中文 165 r=random.randint(5,18) 166 Num = "".join(random.choice("0123456789") for i in range(r)) # 随机数字 #保证qq的唯一性 167 Cnum = "".join(random.choice("123456789") for i in range(1)) # 随机数字 #id 不能选择0 168 try: 169 models.Customer.objects.create(name=Rword, qq=Num, qq_name=Rword, phone=Num, source=1, 170 referral_from=Rword, consult_courses_id=1, content=Rword, 171 consultant_id=Cnum, memo=Rword, date='2018-03-20') 172 except: 173 return HttpResponse('数据重复了。。。') 174 175 return redirect('/DBadd/crm_Customer/') 176 177 178 # ————————03PerfectCRM创建基本数据———————— 179 180 181 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 182 def crm_ContractTemplate(request): 183 if request.method == "GET": 184 user_list = models.ContractTemplate.objects.all() 185 return render(request, 'crm_ContractTemplate.html', {'user_list':user_list}) 186 elif request.method == "POST": 187 try: 188 t= ''' 189 委托方:__{stu_name}__ 190 法定代表人或负责人:__{stu_name}__ 191 服务方:_______ 192 法定代表人或负责人:_________ 193 根据《中华人民共和国合同法》的有关规定,经双方当事人协商一致,签订本 194 合同。 195 第一条 项目名称__{course_name}__。 196 (注:本参考格式适用于下列技术服务活动:进行设计、工艺、制造、试验以 197 及农作物育种,畜禽的饲养等方面的技术指导、讲解技术资料、解决和解答技术问 198 题;进行示范操作;传授计算机软件的编制技术、先进仪器设备的装配,使用技术 199 等等。) 200 第二条 培训的内容和要求:_______。 201 第三条 培训计划、进度、期限:_______。 202 第四条 培训地点和方式:____________。 203 第五条 服务方(教师)的资历和水平:________。 204 第六条 学员的人数和质量:___________。 205 第七条 教员、学员的食宿、交通、医疗费用的支付和安排____。 206 第八条 报酬及其支付方式:__________。 207 第九条 委托方的违约责任:_________。 208 1.委托方未按合同提供培训条件,影响合同履行的,约定的报酬仍应如数支 209 付; 210 2.擅自将服务方要求保密的技术资料引用、发表和提供给第三方,应支付数 211 额为____的违约金; 212 第十条 服务方的违约责任: 213 1.服务方未按合同制订培训计划,影响培训工作质量的,应当减收___% 214 的报酬; 215 2.服务方提供的师资不符合合同要求,服务方有义务予以重新配备;未按合 216 同规定完成培训工作的,应免收报酬。 217 第十一条 保密条款:________ 218 当事人双方应对下列技术资料承担保密义务:______。 219 第十二条 有关技术成果归属条款 220 在履行合同过程中,服务方利用委托方提供的技术资料和工作条件所完成的新 221 的技术成果,属于服务方;委托方利用服务方的工作成果所完成的新技术成果,属 222 于委托方。对新的技术成果享有就该技术成果取得的精神权利(如获得奖金、奖章、 223 荣誉证书的权利)、经济权利(如专利权、非专利技术的转让权,使用权等)和 224 其它利益。 225 第十三条 本合同争议的解决办法:______。 226 本合同自双方当事人签字、盖章后生效。 227 委托方负责人(或授权代表) 服务方负责人(或授权代表) 228 签字:__{stu_name}__(盖章) 签名:____(盖章) 229 签字时间:_________ 签字时间:_________ 230 签字地点:_________ 签字地点:_________ 231 开户银行:_________ 开户银行:_________ 232 帐号:___________ 帐号:___________ 233 委托方担保人(名称):___ 服务方担保人(名称):___ 234 地址:___________ 地址:___________ 235 负责人(或授权代表) 负责人(或授权代表) 236 签字:________(盖章) 签字:________(盖章) 237 签字时间:_________ 签字时间:_________ 238 签字地点:_________ 签字地点:_________ 239 开户银行:_________ 开户银行:_________ 240 帐号:___________ 帐号:___________''' 241 242 models.ContractTemplate.objects.create(name='技术合同:专业技术培训协议',template=t) 243 except: 244 return HttpResponse('数据错误!重复了吧。。。') 245 246 return redirect('/DBadd/crm_ContractTemplate/') 247 248 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
1 {#crm_ContractTemplate.html#} 2 {## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#} 3 <!DOCTYPE html> 4 <html lang="en"> 5 <head> 6 <meta charset="UTF-8"> 7 <title>Title</title> 8 </head> 9 <body> 10 <h3>添加合同</h3> 11 12 <form method="POST" action="/DBadd/crm_ContractTemplate/"> 13 {% csrf_token %} 14 <input type="submit"value="添加"/> 15 </form> 16 17 <h3>合同详细</h3> 18 <ul> 19 {% for row in user_list %} 20 <li> 21 22 <a>{{row.id}}-{{row.name}}</a> 23 <hr> 24 <pre>{{row.template}}</pre> 25 </li> 26 {% endfor %} 27 </ul> 28 29 30 </body> 31 </html> 32 33 {## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
http://127.0.0.1:8000/DBadd/crm_ContractTemplate/
http://127.0.0.1:8000/bpm/customer/registration/1/
您的资助是我最大的动力!
金额随意,欢迎来赏!
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【颜言】!