Django项目:CRM(客户关系管理系统)--63--53PerfectCRM实现CRM客户报名流程缴费
1 #urls.py 2 3 """PerfectCRM URL Configuration 4 5 The `urlpatterns` list routes URLs to views. For more information please see: 6 https://docs.djangoproject.com/en/2.0/topics/http/urls/ 7 Examples: 8 Function views 9 1. Add an import: from my_app import views 10 2. Add a URL to urlpatterns: path('', views.home, name='home') 11 Class-based views 12 1. Add an import: from other_app.views import Home 13 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 14 Including another URLconf 15 1. Import the include() function: from django.urls import include, path 16 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 17 """ 18 from django.contrib import admin 19 from django.urls import path 20 21 # ————————02PerfectCRM创建ADMIN页面———————— 22 from django.conf.urls import url # URL 23 from django.conf.urls import include # 分发URL 24 # ————————02PerfectCRM创建ADMIN页面———————— 25 26 # ————————46PerfectCRM实现登陆后页面才能访问———————— 27 from PerfectCRM import main_views 28 # ————————46PerfectCRM实现登陆后页面才能访问———————— 29 30 urlpatterns = [ 31 path('admin/', admin.site.urls), 32 33 # ————————02PerfectCRM创建ADMIN页面———————— 34 url(r'^king_admin/', include("king_admin.king_urls")), # 自定义admin 35 # ————————02PerfectCRM创建ADMIN页面———————— 36 37 # ————————03PerfectCRM创建基本数据———————— 38 url(r'^DBadd/', include("DBadd.DBadd_urls")), # 添加随机数据 39 # ————————03PerfectCRM创建基本数据———————— 40 # ————————38PerfectCRM实现全局账号登录注销———————— 41 url(r'^gbacc/', include("gbacc.gbacc_urls")), # 全局账号登录注销 42 # ————————38PerfectCRM实现全局账号登录注销———————— 43 44 # ————————42PerfectCRM实现AJAX全局账号注册———————— 45 url(r'^gbacc/', include("gbacc.gbacc_ajax_urls")), # 全局账号登录注销 46 # ————————42PerfectCRM实现AJAX全局账号注册———————— 47 48 # ————————46PerfectCRM实现登陆后页面才能访问———————— 49 url(r'^$', main_views.PortalView.as_view()), 50 # ————————46PerfectCRM实现登陆后页面才能访问———————— 51 52 # ————————47PerfectCRM实现CRM客户报名流程———————— 53 url(r'^bpm/', include("bpm.sales.sales_urls")), # 业务流程 54 # ————————47PerfectCRM实现CRM客户报名流程———————— 55 56 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 57 url(r'^bpm/', include("bpm.financial.financial_urls")), # 财务缴费 58 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 59 60 ]
1 # financial_urls.py 2 3 from django.conf.urls import url 4 from bpm.financial import financial_views 5 6 urlpatterns = [ 7 url(r'^not_payment/$', financial_views.not_payment, name="not_payment"), # 报名流程四 未 缴费 查询 8 url(r'^already_payment/$', financial_views.already_payment, name="already_payment"), # 报名流程四 已 缴费 查询 9 url(r'^payment/(\d+)/$', financial_views.payment, name="payment"), # 报名流程四 缴费 #财务 10 ] 11 # ————————47PerfectCRM实现CRM客户报名流程————————
1 # financial_views.py 2 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 3 from crm import models #数据库 4 from django.shortcuts import redirect,render #页面返回 5 from bpm.bpm_auxiliary import bpm_forms #自定制 forms 6 from django.contrib.auth.decorators import login_required # 登陆后页面才能访问 7 # #待缴费 8 def not_payment(request): 9 sign=models.Enrollment.objects.all()#所有的报名表 10 return render(request, 'bpm_financial/not_payment.html', locals())# 11 # 已缴费 12 def already_payment(request): 13 sign=models.Enrollment.objects.all()#所有的报名表 14 return render(request, 'bpm_financial/already_payment.html', locals())# 15 #缴费视图 16 @login_required # 登陆后页面才能访问 17 def payment(request,enroll_id): 18 sign=models.Payment.objects.all()#所有的报名表#前端对比用户#缴费记录 19 enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象 20 errors={} #错误信息 21 if request.method=="POST": 22 payment_amount=request.POST.get('amount')#缴费金额 23 consultant = models.UserProfile.objects.get(id=request.user.id) #财务人员 #当前登陆人 24 if payment_amount: 25 payment_amount=int(payment_amount) #转数字类型 26 if payment_amount<500: 27 errors['err']='缴费金额不得低于500元!' 28 else: #生成forms 29 payment_obj=models.Payment.objects.create( 30 customer=enroll_obj.customer,##客户表 学员 31 course=enroll_obj.enrolled_class.course,#所报课程 32 consultant=consultant,# 财务人员 33 amount=payment_amount,#缴费金额 34 ) 35 enroll_obj.Pay_cost=True#已缴费 36 enroll_obj.save() #保存 37 enroll_obj.customer.status=0#修改报名状态 为已报名#根据数据库 38 enroll_obj.customer.save() #保存 39 return redirect('/bpm/not_payment')#客户表 40 else: 41 errors['err']='金额不能为空!' 42 else: 43 payment_form= bpm_forms.PaymentForm()#生成表单 44 return render(request, 'bpm_financial/payment.html', locals()) 45 # ————————53PerfectCRM实现CRM客户报名流程缴费————————
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 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 85 status_choices = ((0, '已报名'), (1, '未报名'), (2, '已退学')) 86 status = models.SmallIntegerField(choices=status_choices, default=1) # 学员状态 87 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 88 89 source_choices = ( #客户渠道来源 (内存生成) 90 (0,'转介绍'), 91 (1,'QQ群'), 92 (2,'官网'), 93 (3,'百度推广'), 94 (4,'51CTO'), 95 (5,'知乎'), 96 (6,'市场推广'),) 97 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 98 source = models.SmallIntegerField(choices=source_choices)#客户渠道来源 99 100 #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空 101 referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的 102 103 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 104 consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表 105 106 content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 107 108 #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。 109 tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表 110 111 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 112 consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 113 114 memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空 115 116 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 117 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 118 119 def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 120 return self.qq #返回 #QQ号 121 122 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 123 verbose_name_plural = "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字 124 125 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 126 #合同模版 127 class ContractTemplate(models.Model): 128 name=models.CharField('合同名称',max_length=64,unique=True) 129 template=models.TextField() 130 131 def __str__(self): 132 return self.name 133 class Meta: 134 verbose_name_plural='合同表' 135 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 136 137 138 """05客户跟进表""" 139 class CustomerFollowUp(models.Model): 140 141 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 142 customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到 客户信息表 143 144 content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 145 146 #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 147 consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表 148 149 intention_choices =( #报名状态 150 (0,'2周内报名'), 151 (1,'1个月内报名'), 152 (2,'近期无报名计划'), 153 (3,'已在其它机构报名'), 154 (4,'已报名'), 155 (5,'已拉黑'),) 156 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 157 intention=models.SmallIntegerField(choices=intention_choices) #报名状态 158 159 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 160 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 161 162 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 163 return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态 164 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 165 verbose_name_plural = "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字 166 167 """06学员报名信息表""" 168 class Enrollment(models.Model): 169 # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 170 customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到 客户信息表 171 enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到 班级表 172 consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到 账号表 173 174 # ————————52PerfectCRM实现CRM客户报名流程学生合同审核———————— 175 contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同审核") # 合同审核 176 # ————————52PerfectCRM实现CRM客户报名流程学生合同审核———————— 177 178 #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称 179 contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同 180 contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核 181 182 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 183 Pay_cost= models.BooleanField(default=False,verbose_name="缴费") #缴费状态#是不是交定金 184 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 185 186 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 187 date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 188 189 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 190 return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级 191 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 192 unique_together = ("customer","enrolled_class")#联合索引 193 verbose_name_plural = "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字 194 195 """07缴费记录表""" 196 class Payment(models.Model): 197 #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 198 customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 关联到 客户信息表 199 course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到 课程表 200 201 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500 202 amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额 203 204 #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 205 consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到 账号表 #财务人员 206 207 #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 208 date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增) 209 210 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 211 return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额 212 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 213 verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字 214 215 """08每节课上课纪录表""" 216 class CourseRecord(models.Model): 217 # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 218 from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级 219 220 #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称 221 day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课 222 223 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 224 teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁 关联到 账号表 225 226 #BooleanField布尔值类型#default=True默认(True)不允许出现空字符 227 has_homework = models.BooleanField(default=True) #有没有作业 228 229 # CharField定长文本#名字最长128#Django可空#数据库可以为空 230 homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题 231 232 #TextField无限制长度的文本#Django可空#数据库可以为空 233 homework_content = models.TextField(blank=True,null=True) #作业内容 234 235 #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称 236 outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么 237 238 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 239 date = models.DateField(auto_now_add=True)#创建时间(数据库自增) 240 241 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 242 return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天) 243 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 244 unique_together = ("from_class","day_num") #联合索引 245 verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字 246 247 """09学习纪录""" 248 class StudyRecord(models.Model): 249 # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 250 student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字 关联到 学员报名信息表 251 course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录 # 关联到 每节课上课纪录表 252 253 attendance_choices = (# 本节课上课状态记录 254 (0,"已签到"), 255 (1,"迟到"), 256 (2,"缺勤"), 257 (3,"早退"),) 258 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 259 attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录 260 261 score_choices = (#学习成绩 262 (100,"A+"), 263 (90,"A"), 264 (85,"B+"), 265 (80,"B"), 266 (75,"B-"), 267 (70,"C+"), 268 (65,"C"), 269 (40,"C-"), 270 (-20,"D"), 271 (-50,"COPY"), 272 (0,"N/A"),) 273 #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作 274 score = models.SmallIntegerField(choices=score_choices) #学习成绩 275 276 memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空 277 278 # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读) 279 date = models.DateField(auto_now_add=True)#创建时间(数据库自增) 280 281 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 282 return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩 283 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 284 unique_together = ('student','course_record')#联合索引#学生名字#开课记录 285 verbose_name_plural = "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字 286 287 # ————————34PerfectCRM实现CRM自定义用户———————— 288 # """10账号表""" 289 # class UserProfile(models.Model): 290 # from django.contrib.auth.models import User # 使用django内置的用户表 291 # 292 # #OneToOneField一对一 #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。 293 # user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表 294 # 295 # name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本 296 # 297 # #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空 298 # roles = models.ManyToManyField("Role",blank=True) #角色(权限) # 双向一对多==多对多 299 # 300 # def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 301 # return self.name #返回 #账号名 302 # class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据 303 # verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字 304 # ————————34PerfectCRM实现CRM自定义用户———————— 305 306 # ————————34PerfectCRM实现CRM自定义用户———————— 307 #10账号表,创建用户和超级用户 308 from django.contrib.auth.models import BaseUserManager 309 class UserProfileManager(BaseUserManager): 310 def create_user(self, email, name, password=None): 311 """ 312 创建并保存一个用户用给定的邮件,日期 313 出生和密码。 314 """ 315 if not email:#没有email 报错 316 raise ValueError('用户必须有一个电子邮件地址') 317 318 user = self.model( 319 email=self.normalize_email(email),#验证邮箱格式 320 name=name, 321 ) 322 user.set_password(password)#加密 323 user.is_active = True 324 user.save(using=self._db) 325 return user 326 def create_superuser(self, email, name, password): 327 """ 328 创建并保存一个超级用户具有给定邮件,日期 329 出生和密码。 330 """ 331 user = self.create_user(email, 332 password=password, 333 name=name 334 ) 335 user.is_active = True 336 user.is_superuser = True 337 user.save(using=self._db) 338 return user 339 340 """10账号表""" 341 """ 342 343 #删除数据库 344 345 #调用objects = UserProfileManager()#创建账号 #关联这个函数 346 347 #运行 Terminal 348 # 生成 数据表 349 # python manage.py makemigrations 350 # 数据表 迁移 351 # python manage.py migrate 352 Django Admin里账号密码重置方法 353 #运行 Terminal 354 python manage.py createsuperuser 355 356 Email address: admin@qq.com 357 用户名 : admin 358 Password: admin123456 359 Password (again): admin123456 360 """ 361 from django.contrib.auth.models import AbstractBaseUser 362 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 363 from django.utils.translation import ugettext_lazy as _ # 语言国际化 364 from django.utils.safestring import mark_safe 365 from django.contrib.auth.models import PermissionsMixin 366 # class UserProfile(AbstractBaseUser): 367 class UserProfile(AbstractBaseUser,PermissionsMixin): 368 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 369 email=models.EmailField( 370 verbose_name='邮箱账号', 371 max_length=255, 372 unique=True#唯一 #登陆账号 373 ) 374 name=models.CharField(max_length=32,verbose_name='用户名') 375 376 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 377 password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密码</a>''')) 378 # ————————35PerfectCRM实现CRM重写Admin密码修改———————— 379 380 is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号 381 is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号 382 objects = UserProfileManager()#创建账号 #关联这个函数 383 USERNAME_FIELD ='email'#指定做为 #登陆账号 384 REQUIRED_FIELDS = ['name']#必填字段 385 def get_full_name(self): 386 return self.email 387 def get_short_name(self): 388 #用户确认的电子邮件地址 389 return self.email 390 def __str__(self): 391 return self.name 392 def has_perm(self,perm,obj=None): 393 #指明用户是否被认为活跃的。以反选代替删除帐号。 394 #最简单的可能的答案:是的,总是 395 return True #有效 账号 396 def has_module_perms(self, app_label): 397 #指明用户是否可以登录到这个管理站点。 398 # 最简单的可能的答案:是的,总是 399 return True #职员状态 400 @property 401 def is_staff(self): 402 '''“用户的员工吗?”''' 403 #最简单的可能的答案:所有管理员都是员工 404 return self.is_superuser#是不是超级用户状态 405 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 #settings.py 406 # ————————34PerfectCRM实现CRM自定义用户———————— 407 408 """11角色表""" 409 class Role(models.Model): 410 name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节 411 def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 412 return self.name#返回 #角色名 413 class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据 414 verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字 415 416 """12标签表""" 417 class Tag(models.Model): 418 name = models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复 419 def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。 420 return self.name #返回 #标签名 421 class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据 422 verbose_name_plural = "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字 423 424 # ————————01PerfectCRM基本配置ADMIN————————
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 # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证———————— 28 def clean_qq(self): 29 #print(self.instance.qq,self.cleaned_data['qq'],'9696969696') 30 if self.instance.qq != self.cleaned_data['qq']: #输入的值和 cleaned_data的值 31 self.add_error('qq',"大神,请勿非法修改!") 32 return self.cleaned_data['qq'] 33 34 def clean_consultant(self): 35 if self.instance.consultant != self.cleaned_data['consultant']: 36 self.add_error('consultant',"非法修改!不要尝试!") 37 return self.cleaned_data['consultant'] 38 39 def clean_source(self): 40 if self.instance.source != self.cleaned_data['source']: 41 self.add_error('source',"非法修改!不能通过!") 42 return self.cleaned_data['source'] 43 # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证———————— 44 45 class Meta: 46 model=models.Customer#客户表 47 fields='__all__' 48 exclude=['tags','content','memo','status','referral_from','consult_courses']#排除,不显示 49 readonly_fields=['qq','consultant','source']#不可修改 50 # ————————48PerfectCRM实现CRM客户报名流程学生合同———————— 51 52 53 54 55 # ————————53PerfectCRM实现CRM客户报名流程缴费———————— 56 #缴费记录 57 class PaymentForm(ModelForm): 58 def __new__(cls, *args, **kwargs): 59 for field_name,field_obj in cls.base_fields.items(): 60 field_obj.widget.attrs['class'] = 'form-control'## 前端的样式 61 return ModelForm.__new__(cls) 62 class Meta: 63 model=models.Payment 64 fields='__all__' 65 66 # ————————53PerfectCRM实现CRM客户报名流程缴费————————
1 {#not_audit.html#} 2 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#} 3 {% extends 'bpm_master/bpm_sample.html' %} 4 {% block right-container-content %} {#自定义内容开始 右边页面内容#} 5 <div class="panel-default"> 6 <div class="panel-body"> 7 <h3>待缴费 | <a class="btn btn-info pull" href={% url 'already_payment' %}>已缴费</a></h3> 8 <table class="table table-striped table-responsive"> 9 <thead> 10 <tr> 11 <th>客户名字</th> 12 <th>客户QQ</th> 13 <th>手机号码</th> 14 <th>咨询顾问</th> 15 16 <th>所报班级</th> 17 <th>报名课程顾问</th> 18 <th>合同审核</th> 19 <th>合同状态</th> 20 <th>日期时间</th> 21 </tr> 22 </thead> 23 <tbody> 24 {% for foo in sign %} 25 {# {% if foo.contract_agreed and foo.contract_approved == false %}#} 26 {% if foo.contract_approved and not foo.Pay_cost %} 27 <tr> 28 <td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td> 29 <td>{{ foo.customer }}</td> 30 <td>{{ foo.customer.phone }}</td> 31 <td>{{ foo.customer.consultant }}</td> 32 33 <td>{{ foo.enrolled_class }}</td> 34 <td>{{ foo.consultant }}</td> 35 <td>{{ foo.contract_review }}</td> 36 <td>{{ foo.contract_approved }}</td> 37 <td>{{ foo.date }}</td> 38 </tr> 39 {% endif %} 40 {% endfor %} 41 </tbody> 42 </table> 43 </div> 44 </div> 45 {% endblock %} 46 47 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
1 {#already_payment.html#} 2 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#} 3 {% extends 'bpm_master/bpm_sample.html' %} 4 {% block right-container-content %} {#自定义内容开始 右边页面内容#} 5 <div class="panel-default"> 6 <div class="panel-body"> 7 <h3>已缴费 | <a class="btn btn-success pull" href={% url 'not_payment' %}>待缴费</a></h3> 8 <table class="table table-striped table-responsive"> 9 <thead> 10 <tr> 11 <th>客户名字</th> 12 <th>客户QQ</th> 13 <th>手机号码</th> 14 <th>咨询顾问</th> 15 16 <th>所报班级</th> 17 <th>报名课程顾问</th> 18 <th>合同审核</th> 19 <th>合同状态</th> 20 <th>日期时间</th> 21 </tr> 22 </thead> 23 <tbody> 24 {% for foo in sign %} 25 {# {% if foo.contract_agreed and foo.contract_approved == false %}#} 26 {% if foo.contract_approved and foo.Pay_cost %} 27 <tr> 28 <td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td> 29 <td>{{ foo.customer }}</td> 30 <td>{{ foo.customer.phone }}</td> 31 <td>{{ foo.customer.consultant }}</td> 32 33 <td>{{ foo.enrolled_class }}</td> 34 <td>{{ foo.consultant }}</td> 35 <td>{{ foo.contract_review }}</td> 36 <td>{{ foo.contract_approved }}</td> 37 <td>{{ foo.date }}</td> 38 </tr> 39 {% endif %} 40 {% endfor %} 41 </tbody> 42 </table> 43 </div> 44 </div> 45 {% endblock %} 46 47 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
1 {#payment.html#} 2 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#} 3 {% extends 'bpm_master/bpm_sample.html' %} 4 {% block right-container-content %} {#自定义内容开始 右边页面内容#} 5 <div class="panel panel-info"> 6 <h4> 学员缴费:</h4> 7 </div> 8 <div id="content"> 9 <form action="" class="form-horizontal col-lg-5" role="form" method="post">{% csrf_token %} 10 <table> 11 <div class="form-group"> 12 <label for="inputeEmail4" class="col-sm-3"> 客户名字: </label> 13 <div class="col-sm-3"> {{ enroll_obj.customer.name }}</div> 14 </div> 15 <div class="form-group"> 16 <label for="inputeEmail4" class="col-sm-3"> 客户QQ: </label> 17 <div class="col-sm-3"> {{ enroll_obj.customer }}</div> 18 </div> 19 <div class="form-group"> 20 <label for="inputeEmail4" class="col-sm-3"> 手机号码: </label> 21 <div class="col-sm-3"> {{ enroll_obj.customer.phone }}</div> 22 </div> 23 <div class="form-group"> 24 <label for="inputeEmail4" class="col-sm-3">咨询顾问 : </label> 25 <div class="col-sm-3"> {{ enroll_obj.customer.consultant }} </div> 26 </div> 27 <div class="form-group"> 28 <label for="inputeEmail4" class="col-sm-3"> 所报课程 : </label> 29 <div class="col-sm-3"> {{ enroll_obj.enrolled_class }} </div> 30 </div> 31 <div class="form-group"> 32 <label for="inputeEmail4" class="col-sm-3">报名课程顾问 : </label> 33 <div class="col-sm-3"> {{ enroll_obj.consultant }} </div> 34 </div> 35 <div class="form-group"> 36 <label for="inputeEmail4" class="col-sm-3">合同审核 : </label> 37 <div class="col-sm-3"> {{ enroll_obj.contract_review }} </div> 38 </div> 39 <div class="form-group"> 40 <label for="inputeEmail9" class="col-sm-3">缴费金额 :</label> 41 <div><input type="text" name="amount" placeholder="至少不低于500"> 42 <span style="color: #c7254e">{{ errors.err }}</span> 43 </div> 44 </div> 45 <div class="form-group"> 46 <label for="inputeEmail9" class="col-sm-3">财务人员 :</label> 47 <div class="col-sm-3"> {{ request.user.name }} </div> 48 </div> 49 </table> 50 <div class="form-group col-sm-6"> 51 <a class="btn btn-danger pull " href={% url 'not_payment' %}>返回</a> 52 <input type="submit" class="btn btn-success pull-right " value="缴费"> 53 </div> 54 </form> 55 56 57 <hr> 58 <table class="table table-striped table-responsive"> 59 <thead> 60 <tr> 61 <th>客户名字</th> 62 <th>客户QQ</th> 63 <th>手机号码</th> 64 <th>咨询顾问</th> 65 <th>所报课程</th> 66 67 <th>报名课程顾问</th> 68 <th>合同审核</th> 69 70 <th>缴费金额</th> 71 <th>财务人员</th> 72 <th>日期时间</th> 73 </tr> 74 </thead> 75 <tbody> 76 {% for foo in sign %} 77 {% if foo.customer == enroll_obj.customer %} 78 <tr> 79 <td>{{ foo.customer.name }}</td> 80 <td>{{ foo.customer }}</td> 81 <td>{{ foo.customer.phone }}</td> 82 <td>{{ foo.customer.consultant }}</td> 83 <td>{{ foo.course }}</td> 84 85 <td>{{ enroll_obj.consultant }}</td> 86 <td>{{ enroll_obj.contract_review }}</td> 87 88 <td>{{ foo.amount }}</td> 89 <td>{{ foo.consultant }}</td> 90 <td>{{ foo.date }}</td> 91 </tr> 92 {% endif %} 93 {% endfor %} 94 </tbody> 95 </table> 96 </div> 97 {% endblock %} 98 {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
您的资助是我最大的动力!
金额随意,欢迎来赏!
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【颜言】!