Django项目:CRM(客户关系管理系统)--63--53PerfectCRM实现CRM客户报名流程缴费
- #urls.py
- """PerfectCRM URL Configuration
- The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/2.0/topics/http/urls/
- Examples:
- Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: path('', views.home, name='home')
- Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
- Including another URLconf
- 1. Import the include() function: from django.urls import include, path
- 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
- """
- from django.contrib import admin
- from django.urls import path
- # ————————02PerfectCRM创建ADMIN页面————————
- from django.conf.urls import url # URL
- from django.conf.urls import include # 分发URL
- # ————————02PerfectCRM创建ADMIN页面————————
- # ————————46PerfectCRM实现登陆后页面才能访问————————
- from PerfectCRM import main_views
- # ————————46PerfectCRM实现登陆后页面才能访问————————
- urlpatterns = [
- path('admin/', admin.site.urls),
- # ————————02PerfectCRM创建ADMIN页面————————
- url(r'^king_admin/', include("king_admin.king_urls")), # 自定义admin
- # ————————02PerfectCRM创建ADMIN页面————————
- # ————————03PerfectCRM创建基本数据————————
- url(r'^DBadd/', include("DBadd.DBadd_urls")), # 添加随机数据
- # ————————03PerfectCRM创建基本数据————————
- # ————————38PerfectCRM实现全局账号登录注销————————
- url(r'^gbacc/', include("gbacc.gbacc_urls")), # 全局账号登录注销
- # ————————38PerfectCRM实现全局账号登录注销————————
- # ————————42PerfectCRM实现AJAX全局账号注册————————
- url(r'^gbacc/', include("gbacc.gbacc_ajax_urls")), # 全局账号登录注销
- # ————————42PerfectCRM实现AJAX全局账号注册————————
- # ————————46PerfectCRM实现登陆后页面才能访问————————
- url(r'^$', main_views.PortalView.as_view()),
- # ————————46PerfectCRM实现登陆后页面才能访问————————
- # ————————47PerfectCRM实现CRM客户报名流程————————
- url(r'^bpm/', include("bpm.sales.sales_urls")), # 业务流程
- # ————————47PerfectCRM实现CRM客户报名流程————————
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- url(r'^bpm/', include("bpm.financial.financial_urls")), # 财务缴费
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- ]
#urls.py
- # financial_urls.py
- from django.conf.urls import url
- from bpm.financial import financial_views
- urlpatterns = [
- url(r'^not_payment/$', financial_views.not_payment, name="not_payment"), # 报名流程四 未 缴费 查询
- url(r'^already_payment/$', financial_views.already_payment, name="already_payment"), # 报名流程四 已 缴费 查询
- url(r'^payment/(\d+)/$', financial_views.payment, name="payment"), # 报名流程四 缴费 #财务
- ]
- # ————————47PerfectCRM实现CRM客户报名流程————————
# financial_urls.py
- # financial_views.py
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- from crm import models #数据库
- from django.shortcuts import redirect,render #页面返回
- from bpm.bpm_auxiliary import bpm_forms #自定制 forms
- from django.contrib.auth.decorators import login_required # 登陆后页面才能访问
- # #待缴费
- def not_payment(request):
- sign=models.Enrollment.objects.all()#所有的报名表
- return render(request, 'bpm_financial/not_payment.html', locals())#
- # 已缴费
- def already_payment(request):
- sign=models.Enrollment.objects.all()#所有的报名表
- return render(request, 'bpm_financial/already_payment.html', locals())#
- #缴费视图
- @login_required # 登陆后页面才能访问
- def payment(request,enroll_id):
- sign=models.Payment.objects.all()#所有的报名表#前端对比用户#缴费记录
- enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象
- errors={} #错误信息
- if request.method=="POST":
- payment_amount=request.POST.get('amount')#缴费金额
- consultant = models.UserProfile.objects.get(id=request.user.id) #财务人员 #当前登陆人
- if payment_amount:
- payment_amount=int(payment_amount) #转数字类型
- if payment_amount<500:
- errors['err']='缴费金额不得低于500元!'
- else: #生成forms
- payment_obj=models.Payment.objects.create(
- customer=enroll_obj.customer,##客户表 学员
- course=enroll_obj.enrolled_class.course,#所报课程
- consultant=consultant,# 财务人员
- amount=payment_amount,#缴费金额
- )
- enroll_obj.Pay_cost=True#已缴费
- enroll_obj.save() #保存
- enroll_obj.customer.status=0#修改报名状态 为已报名#根据数据库
- enroll_obj.customer.save() #保存
- return redirect('/bpm/not_payment')#客户表
- else:
- errors['err']='金额不能为空!'
- else:
- payment_form= bpm_forms.PaymentForm()#生成表单
- return render(request, 'bpm_financial/payment.html', locals())
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
# financial_views.py
- #models.py
- # ————————01PerfectCRM基本配置ADMIN————————
- from django.db import models
- # Create your models here.
- """
- #运行 Terminal
- # 生成 数据表
- # python manage.py makemigrations
- # 数据表 迁移
- # python manage.py migrate
- """
- """01校区表"""
- class Branch(models.Model):
- name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型
- addr = models.CharField(max_length=128) #地址
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return self.name #返回 #校区名
- class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字
- """02班级表"""
- class ClassList(models.Model):
- #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区 关联到 校区表
- course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程 关联到 课程表
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE) # 合同表
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- class_type_choices = ( #上课形式
- (0,'面授(脱产)'),
- (1,'面授(周末)'),
- (2,'网络班'),)
- #PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
- class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式
- #PositiveSmallIntegerField正小整数 0 ~ 32767
- semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期
- #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
- teachers = models.ManyToManyField("UserProfile") # 老师 关联到 账号表
- start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称
- # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空
- end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- unique_together=('branch','course','semester') #联合索引
- verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字
- """03课程表,可以报名那些课程"""
- class Course(models.Model):
- name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型
- price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767
- period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767
- outline = models.TextField() #课程大纲 #文本类型
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return self.name #返回 #课程名
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字
- '''04客户信息表'''
- class Customer(models.Model):
- name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空
- qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复
- qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
- phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号
- email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email
- sex_choices=((0,'保密'),(1,'男'),(2,'女'))
- sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别')
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- status_choices = ((0, '已报名'), (1, '未报名'), (2, '已退学'))
- status = models.SmallIntegerField(choices=status_choices, default=1) # 学员状态
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- source_choices = ( #客户渠道来源 (内存生成)
- (0,'转介绍'),
- (1,'QQ群'),
- (2,'官网'),
- (3,'百度推广'),
- (4,'51CTO'),
- (5,'知乎'),
- (6,'市场推广'),)
- #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
- source = models.SmallIntegerField(choices=source_choices)#客户渠道来源
- #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空
- referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的
- #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表
- content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
- #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
- tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表
- #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表
- memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空
- #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return self.qq #返回 #QQ号
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- #合同模版
- class ContractTemplate(models.Model):
- name=models.CharField('合同名称',max_length=64,unique=True)
- template=models.TextField()
- def __str__(self):
- return self.name
- class Meta:
- verbose_name_plural='合同表'
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- """05客户跟进表"""
- class CustomerFollowUp(models.Model):
- #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到 客户信息表
- content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
- #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到 账号表
- intention_choices =( #报名状态
- (0,'2周内报名'),
- (1,'1个月内报名'),
- (2,'近期无报名计划'),
- (3,'已在其它机构报名'),
- (4,'已报名'),
- (5,'已拉黑'),)
- #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
- intention=models.SmallIntegerField(choices=intention_choices) #报名状态
- #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字
- """06学员报名信息表"""
- class Enrollment(models.Model):
- # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到 客户信息表
- enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到 班级表
- consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到 账号表
- # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
- contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同审核") # 合同审核
- # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
- #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称
- contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同
- contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- Pay_cost= models.BooleanField(default=False,verbose_name="缴费") #缴费状态#是不是交定金
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- unique_together = ("customer","enrolled_class")#联合索引
- verbose_name_plural = "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字
- """07缴费记录表"""
- class Payment(models.Model):
- #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 关联到 客户信息表
- course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到 课程表
- #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500
- amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额
- #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到 账号表 #财务人员
- #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字
- """08每节课上课纪录表"""
- class CourseRecord(models.Model):
- # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级
- #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称
- day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课
- # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁 关联到 账号表
- #BooleanField布尔值类型#default=True默认(True)不允许出现空字符
- has_homework = models.BooleanField(default=True) #有没有作业
- # CharField定长文本#名字最长128#Django可空#数据库可以为空
- homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题
- #TextField无限制长度的文本#Django可空#数据库可以为空
- homework_content = models.TextField(blank=True,null=True) #作业内容
- #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
- outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么
- # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天)
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- unique_together = ("from_class","day_num") #联合索引
- verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字
- """09学习纪录"""
- class StudyRecord(models.Model):
- # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字 关联到 学员报名信息表
- course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录 # 关联到 每节课上课纪录表
- attendance_choices = (# 本节课上课状态记录
- (0,"已签到"),
- (1,"迟到"),
- (2,"缺勤"),
- (3,"早退"),)
- #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
- attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录
- score_choices = (#学习成绩
- (100,"A+"),
- (90,"A"),
- (85,"B+"),
- (80,"B"),
- (75,"B-"),
- (70,"C+"),
- (65,"C"),
- (40,"C-"),
- (-20,"D"),
- (-50,"COPY"),
- (0,"N/A"),)
- #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
- score = models.SmallIntegerField(choices=score_choices) #学习成绩
- memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空
- # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
- date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- unique_together = ('student','course_record')#联合索引#学生名字#开课记录
- verbose_name_plural = "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字
- # ————————34PerfectCRM实现CRM自定义用户————————
- # """10账号表"""
- # class UserProfile(models.Model):
- # from django.contrib.auth.models import User # 使用django内置的用户表
- #
- # #OneToOneField一对一 #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
- # user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表
- #
- # name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本
- #
- # #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空
- # roles = models.ManyToManyField("Role",blank=True) #角色(权限) # 双向一对多==多对多
- #
- # def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- # return self.name #返回 #账号名
- # class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- # verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字
- # ————————34PerfectCRM实现CRM自定义用户————————
- # ————————34PerfectCRM实现CRM自定义用户————————
- #10账号表,创建用户和超级用户
- from django.contrib.auth.models import BaseUserManager
- class UserProfileManager(BaseUserManager):
- def create_user(self, email, name, password=None):
- """
- 创建并保存一个用户用给定的邮件,日期
- 出生和密码。
- """
- if not email:#没有email 报错
- raise ValueError('用户必须有一个电子邮件地址')
- user = self.model(
- email=self.normalize_email(email),#验证邮箱格式
- name=name,
- )
- user.set_password(password)#加密
- user.is_active = True
- user.save(using=self._db)
- return user
- def create_superuser(self, email, name, password):
- """
- 创建并保存一个超级用户具有给定邮件,日期
- 出生和密码。
- """
- user = self.create_user(email,
- password=password,
- name=name
- )
- user.is_active = True
- user.is_superuser = True
- user.save(using=self._db)
- return user
- """10账号表"""
- """
- #删除数据库
- #调用objects = UserProfileManager()#创建账号 #关联这个函数
- #运行 Terminal
- # 生成 数据表
- # python manage.py makemigrations
- # 数据表 迁移
- # python manage.py migrate
- Django Admin里账号密码重置方法
- #运行 Terminal
- python manage.py createsuperuser
- Email address: admin@qq.com
- 用户名 : admin
- Password: admin123456
- Password (again): admin123456
- """
- from django.contrib.auth.models import AbstractBaseUser
- # ————————35PerfectCRM实现CRM重写Admin密码修改————————
- from django.utils.translation import ugettext_lazy as _ # 语言国际化
- from django.utils.safestring import mark_safe
- from django.contrib.auth.models import PermissionsMixin
- # class UserProfile(AbstractBaseUser):
- class UserProfile(AbstractBaseUser,PermissionsMixin):
- # ————————35PerfectCRM实现CRM重写Admin密码修改————————
- email=models.EmailField(
- verbose_name='邮箱账号',
- max_length=255,
- unique=True#唯一 #登陆账号
- )
- name=models.CharField(max_length=32,verbose_name='用户名')
- # ————————35PerfectCRM实现CRM重写Admin密码修改————————
- password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密码</a>'''))
- # ————————35PerfectCRM实现CRM重写Admin密码修改————————
- is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号
- is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号
- objects = UserProfileManager()#创建账号 #关联这个函数
- USERNAME_FIELD ='email'#指定做为 #登陆账号
- REQUIRED_FIELDS = ['name']#必填字段
- def get_full_name(self):
- return self.email
- def get_short_name(self):
- #用户确认的电子邮件地址
- return self.email
- def __str__(self):
- return self.name
- def has_perm(self,perm,obj=None):
- #指明用户是否被认为活跃的。以反选代替删除帐号。
- #最简单的可能的答案:是的,总是
- return True #有效 账号
- def has_module_perms(self, app_label):
- #指明用户是否可以登录到这个管理站点。
- # 最简单的可能的答案:是的,总是
- return True #职员状态
- @property
- def is_staff(self):
- '''“用户的员工吗?”'''
- #最简单的可能的答案:所有管理员都是员工
- return self.is_superuser#是不是超级用户状态
- # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单 #settings.py
- # ————————34PerfectCRM实现CRM自定义用户————————
- """11角色表"""
- class Role(models.Model):
- name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节
- def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return self.name#返回 #角色名
- class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字
- """12标签表"""
- class Tag(models.Model):
- name = models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复
- def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
- return self.name #返回 #标签名
- class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
- verbose_name_plural = "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字
- # ————————01PerfectCRM基本配置ADMIN————————
#models.py
- # forms.py
- # ————————47PerfectCRM实现CRM客户报名流程————————
- from crm import models #数据库
- from django.forms import ModelForm #继承forms自定制
- #报名 销售填写
- class EnrollmentForm(ModelForm):
- def __new__(cls, *args, **kwargs):
- for field_name,field_obj in cls.base_fields.items():
- field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
- return ModelForm.__new__(cls)
- class Meta:
- model= models.Enrollment
- fields= ['enrolled_class']
- # ————————47PerfectCRM实现CRM客户报名流程————————
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- #报名学员填 写
- class CustomerForm(ModelForm):
- def __new__(cls, *args, **kwargs):
- for field_name,field_obj in cls.base_fields.items():
- field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
- if field_name in cls.Meta.readonly_fields:#如果不可修改
- field_obj.widget.attrs['disabled'] = True## 前端的样式 灰色
- return ModelForm.__new__(cls)
- # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————
- def clean_qq(self):
- #print(self.instance.qq,self.cleaned_data['qq'],'9696969696')
- if self.instance.qq != self.cleaned_data['qq']: #输入的值和 cleaned_data的值
- self.add_error('qq',"大神,请勿非法修改!")
- return self.cleaned_data['qq']
- def clean_consultant(self):
- if self.instance.consultant != self.cleaned_data['consultant']:
- self.add_error('consultant',"非法修改!不要尝试!")
- return self.cleaned_data['consultant']
- def clean_source(self):
- if self.instance.source != self.cleaned_data['source']:
- self.add_error('source',"非法修改!不能通过!")
- return self.cleaned_data['source']
- # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————
- class Meta:
- model=models.Customer#客户表
- fields='__all__'
- exclude=['tags','content','memo','status','referral_from','consult_courses']#排除,不显示
- readonly_fields=['qq','consultant','source']#不可修改
- # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
- #缴费记录
- class PaymentForm(ModelForm):
- def __new__(cls, *args, **kwargs):
- for field_name,field_obj in cls.base_fields.items():
- field_obj.widget.attrs['class'] = 'form-control'## 前端的样式
- return ModelForm.__new__(cls)
- class Meta:
- model=models.Payment
- fields='__all__'
- # ————————53PerfectCRM实现CRM客户报名流程缴费————————
# forms.py
- {#not_audit.html#}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
- {% extends 'bpm_master/bpm_sample.html' %}
- {% block right-container-content %} {#自定义内容开始 右边页面内容#}
- <div class="panel-default">
- <div class="panel-body">
- <h3>待缴费 | <a class="btn btn-info pull" href={% url 'already_payment' %}>已缴费</a></h3>
- <table class="table table-striped table-responsive">
- <thead>
- <tr>
- <th>客户名字</th>
- <th>客户QQ</th>
- <th>手机号码</th>
- <th>咨询顾问</th>
- <th>所报班级</th>
- <th>报名课程顾问</th>
- <th>合同审核</th>
- <th>合同状态</th>
- <th>日期时间</th>
- </tr>
- </thead>
- <tbody>
- {% for foo in sign %}
- {# {% if foo.contract_agreed and foo.contract_approved == false %}#}
- {% if foo.contract_approved and not foo.Pay_cost %}
- <tr>
- <td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td>
- <td>{{ foo.customer }}</td>
- <td>{{ foo.customer.phone }}</td>
- <td>{{ foo.customer.consultant }}</td>
- <td>{{ foo.enrolled_class }}</td>
- <td>{{ foo.consultant }}</td>
- <td>{{ foo.contract_review }}</td>
- <td>{{ foo.contract_approved }}</td>
- <td>{{ foo.date }}</td>
- </tr>
- {% endif %}
- {% endfor %}
- </tbody>
- </table>
- </div>
- </div>
- {% endblock %}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{#not_audit.html#}
- {#already_payment.html#}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
- {% extends 'bpm_master/bpm_sample.html' %}
- {% block right-container-content %} {#自定义内容开始 右边页面内容#}
- <div class="panel-default">
- <div class="panel-body">
- <h3>已缴费 | <a class="btn btn-success pull" href={% url 'not_payment' %}>待缴费</a></h3>
- <table class="table table-striped table-responsive">
- <thead>
- <tr>
- <th>客户名字</th>
- <th>客户QQ</th>
- <th>手机号码</th>
- <th>咨询顾问</th>
- <th>所报班级</th>
- <th>报名课程顾问</th>
- <th>合同审核</th>
- <th>合同状态</th>
- <th>日期时间</th>
- </tr>
- </thead>
- <tbody>
- {% for foo in sign %}
- {# {% if foo.contract_agreed and foo.contract_approved == false %}#}
- {% if foo.contract_approved and foo.Pay_cost %}
- <tr>
- <td><a href="{% url 'payment' foo.id %}">{{ foo.customer.name }}</a></td>
- <td>{{ foo.customer }}</td>
- <td>{{ foo.customer.phone }}</td>
- <td>{{ foo.customer.consultant }}</td>
- <td>{{ foo.enrolled_class }}</td>
- <td>{{ foo.consultant }}</td>
- <td>{{ foo.contract_review }}</td>
- <td>{{ foo.contract_approved }}</td>
- <td>{{ foo.date }}</td>
- </tr>
- {% endif %}
- {% endfor %}
- </tbody>
- </table>
- </div>
- </div>
- {% endblock %}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{#already_payment.html#}
- {#payment.html#}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
- {% extends 'bpm_master/bpm_sample.html' %}
- {% block right-container-content %} {#自定义内容开始 右边页面内容#}
- <div class="panel panel-info">
- <h4> 学员缴费:</h4>
- </div>
- <div id="content">
- <form action="" class="form-horizontal col-lg-5" role="form" method="post">{% csrf_token %}
- <table>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3"> 客户名字: </label>
- <div class="col-sm-3"> {{ enroll_obj.customer.name }}</div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3"> 客户QQ: </label>
- <div class="col-sm-3"> {{ enroll_obj.customer }}</div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3"> 手机号码: </label>
- <div class="col-sm-3"> {{ enroll_obj.customer.phone }}</div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3">咨询顾问 : </label>
- <div class="col-sm-3"> {{ enroll_obj.customer.consultant }} </div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3"> 所报课程 : </label>
- <div class="col-sm-3"> {{ enroll_obj.enrolled_class }} </div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3">报名课程顾问 : </label>
- <div class="col-sm-3"> {{ enroll_obj.consultant }} </div>
- </div>
- <div class="form-group">
- <label for="inputeEmail4" class="col-sm-3">合同审核 : </label>
- <div class="col-sm-3"> {{ enroll_obj.contract_review }} </div>
- </div>
- <div class="form-group">
- <label for="inputeEmail9" class="col-sm-3">缴费金额 :</label>
- <div><input type="text" name="amount" placeholder="至少不低于500">
- <span style="color: #c7254e">{{ errors.err }}</span>
- </div>
- </div>
- <div class="form-group">
- <label for="inputeEmail9" class="col-sm-3">财务人员 :</label>
- <div class="col-sm-3"> {{ request.user.name }} </div>
- </div>
- </table>
- <div class="form-group col-sm-6">
- <a class="btn btn-danger pull " href={% url 'not_payment' %}>返回</a>
- <input type="submit" class="btn btn-success pull-right " value="缴费">
- </div>
- </form>
- <hr>
- <table class="table table-striped table-responsive">
- <thead>
- <tr>
- <th>客户名字</th>
- <th>客户QQ</th>
- <th>手机号码</th>
- <th>咨询顾问</th>
- <th>所报课程</th>
- <th>报名课程顾问</th>
- <th>合同审核</th>
- <th>缴费金额</th>
- <th>财务人员</th>
- <th>日期时间</th>
- </tr>
- </thead>
- <tbody>
- {% for foo in sign %}
- {% if foo.customer == enroll_obj.customer %}
- <tr>
- <td>{{ foo.customer.name }}</td>
- <td>{{ foo.customer }}</td>
- <td>{{ foo.customer.phone }}</td>
- <td>{{ foo.customer.consultant }}</td>
- <td>{{ foo.course }}</td>
- <td>{{ enroll_obj.consultant }}</td>
- <td>{{ enroll_obj.contract_review }}</td>
- <td>{{ foo.amount }}</td>
- <td>{{ foo.consultant }}</td>
- <td>{{ foo.date }}</td>
- </tr>
- {% endif %}
- {% endfor %}
- </tbody>
- </table>
- </div>
- {% endblock %}
- {## # ————————53PerfectCRM实现CRM客户报名流程缴费————————#}
{#payment.html#}
Django项目:CRM(客户关系管理系统)--63--53PerfectCRM实现CRM客户报名流程缴费的更多相关文章
- 文献综述二十:基于UML技术的客户关系管理系统实现
一.基本信息 标题:基于UML技术的客户关系管理系统实现 时间:2015 出版源:电子设计工程 文件分类:uml技术的研究 二.研究背景 设计出可应用与银行和储户之间沟通的客户关系管理系统,从而实现对 ...
- Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
- Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
- Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色
#models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...
- Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录
#urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...
- Django项目:CRM(客户关系管理系统)--78--68PerfectCRM实现CRM业务流程(bpm)报名缴费分页
# pagination.py # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— from django.utils.safestring impo ...
- Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业
# teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...
- Django项目:CRM(客户关系管理系统)--71--61PerfectCRM实现CRM学生上传作业
# student_urls.py # ————————60PerfectCRM实现CRM学生上课记录———————— from django.conf.urls import url from bp ...
- Django项目:CRM(客户关系管理系统)--67--57PerfectCRM实现admin批量生成上课记录
#admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...
随机推荐
- echarts折线区域图
一.使用场景 当舒张压和收缩压超过或低于他们对应的范围时,折线应该给与不同颜色.两个指标对应的范围也要填充不同的颜色. 二.实现方案 主要使用了echarts中的visualMap,series.ma ...
- https://stackoverflow.com/与程序相关的IT技术问答网站
https://stackoverflow.com/ Stack Overflow是一个与程序相关的IT技术问答网站.用户可以在网站免费提交问题,浏览问题,索引相关内容,在创建主页的时候使用简单的HT ...
- HTML引入CSS的方法
1.嵌入式 通过<style>标记,来引入CSS样式. 语法格式:<style type = “text/css”></style> 提示:<style> ...
- Acess link
- Spring事物管理机制简单学习
首先spring并不直接管理事物,而是提供了多种事物管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现. Spring管理事物的接口是org.s ...
- 王者归来,Java 程序设计葵花宝典!
致谢 感谢所有关注本号的小伙伴们,这一年来本号的茁壮成长离不开大家的支持. 2018年,继续坚持分享以及为大家谋求福利!!! Java技术栈往期赠书 赠书一:新春第一次送书,价值78元 X 3本 赠 ...
- spring boot发简单文本邮件
首先要去邮箱打开POP3/SMTP权限: 然后会提供个授权码,用来发送邮件.忘记了,可以点生成授权码再次生成. 1.引入spring boot自带的mail依赖,这里版本用的:<spring-b ...
- 关于ueditor 文本框
遇到一个问题,需要将从ueditor中的获得的带格式的文本,从数据库中取出,在放回到 ueditor中去,但是 文本中\n总是截断字符串,出现 这种情况,后面的字符就不能算到里面去了,程序就报错了. ...
- 多重背包 /// 单调队列DP oj1943
题目大意: em.... 就是多重背包 挑战340页的东西 ...自己的笔记总结总是比较乱的 重点:原始的状态转移方程中 更新第 i 种物品时 重量%w[i] 的值不同 则它们之间是相互独立的: 1- ...
- jQuery实现contains方法不区分大小写的方法教程
jQuery.expr[':'].Contains = function(a, i, m){ return jQuery(a).text().toUpperCase() .indexOf(m[3].t ...