#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()时应该返回的值。
# ————————57PerfectCRM实现admin批量生成上课记录————————
# return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
return " 学员:%s |QQ: %s |班级:%s" %(self.customer.name,self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
# ————————57PerfectCRM实现admin批量生成上课记录————————
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) # 本节课上课状态记录 # ————————63PerfectCRM实现CRM讲师下载作业————————
delivery = models.BooleanField(default=False,verbose_name="交作业") #有没有交付作业
# ————————63PerfectCRM实现CRM讲师下载作业———————— # ————————61PerfectCRM实现CRM学生上传作业————————
homework_link = models.TextField(blank=True,null=True)#作业链接 #TextField无限制长度的文本#Django可空#数据库可以为空
# ————————61PerfectCRM实现CRM学生上传作业———————— 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='用户名') # ————————72PerfectCRM实现CRM动态菜单和角色————————
branch = models.ForeignKey( "Branch", verbose_name="所属校区", blank=True, null=True, on_delete=models.CASCADE )
roles = models.ManyToManyField( 'Role', verbose_name="角色", blank=True )
memo = models.TextField( blank=True, null=True, default=None, verbose_name="备注" )
from django.utils import timezone
date_joined = models.DateTimeField( verbose_name="创建时间", default=timezone.now )
# ————————72PerfectCRM实现CRM动态菜单和角色———————— # ————————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']#必填字段 # ————————60PerfectCRM实现CRM学生上课记录————————
stu_account = models.ForeignKey( "Customer", verbose_name='关联学员帐号', blank=True, null=True, on_delete=models.CASCADE,
help_text='报名成功后创建关联帐户' )
# ————————60PerfectCRM实现CRM学生上课记录———————— 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自定义用户————————
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————
class Meta:
verbose_name_plural = '10CRM账户表'
permissions = (
('crm_010101_all_table_data_list_GET', '010101_全部查看数据_GET'),
('crm_010102_all_table_data_list_POST', '010102_全部查看数据_POST'),
('crm_010103_all_table_add_GET', '010103_全部添加数据_GET'),
('crm_010104_all_table_add_POST', '010104_全部添加数据_POST'),
('crm_010105_all_table_change_GET', '010105_全部修改数据_GET'),
('crm_010106_all_table_change_POST', '010106_全部修改数据_POST'),
('crm_010107_all_table_delete_GET', '010107_全部删除数据_GET'),
('crm_010108_all_table_delete_POST', '010108_全部删除数据_POST'),
('crm_010109_all_password_reset_GET', '010109_全部密码重置_GET'),
('crm_010110_all_password_reset_POST', '010110_全部密码重置_POST'), ('crm_010201_only_view_Branch_GET', '010201_只能查看校区表_GET'),
('crm_010202_only_view_Branch_POST', '010202_只能查看校区表_POST'),
('crm_010203_only_add_Branch_GET', '010203_只能添加校区表_GET'),
('crm_010204_only_add_Branch_POST', '010204_只能添加校区表_POST'),
('crm_010205_only_change_Branch_GET', '010205_只能修改校区表_GET'),
('crm_010206_only_change_Branch_POST', '010206_只能修改校区表_POST'),
('crm_010207_only_delete_Branch_GET', '010207_只能删除校区表_GET'),
('crm_010208_only_delete_Branch_POST', '010208_只能删除校区表_POST'), ('crm_010301_only_view_ClassList_GET', '010301_只能查看班级表_GET'),
('crm_010302_only_view_ClassList_POST', '010302_只能查看班级表_POST'),
('crm_010303_only_add_ClassList_GET', '010303_只能添加班级表_GET'),
('crm_010304_only_add_ClassList_POST', '010304_只能添加班级表_POST'),
('crm_010305_only_change_ClassList_GET', '010305_只能修改班级表_GET'),
('crm_010306_only_change_ClassList_POST', '010306_只能修改班级表_POST'),
('crm_010307_only_delete_ClassList_GET', '010307_只能删除班级表_GET'),
('crm_010308_only_delete_ClassList_POST', '010308_只能删除班级表_POST'), ('crm_010401_only_view_Course_GET', '010401_只能查看课程表_GET'),
('crm_010402_only_view_Course_POST', '010402_只能查看课程表_POST'),
('crm_010403_only_add_Course_GET', '010403_只能添加课程表_GET'),
('crm_010404_only_add_Course_POST', '010404_只能添加课程表_POST'),
('crm_010405_only_change_Course_GET', '010405_只能修改课程表_GET'),
('crm_010406_only_change_Course_POST', '010406_只能修改课程表_POST'),
('crm_010407_only_delete_Course_GET', '010407_只能删除课程表_GET'),
('crm_010408_only_delete_Course_POST', '010408_只能删除课程表_POST'), ('crm_010501_only_view_Customer_GET', '010501_只能查看客户表_GET'),
('crm_010502_only_view_Customer_POST', '010502_只能查看客户表_POST'),
('crm_010503_only_add_Customer_GET', '010503_只能添加客户表_GET'),
('crm_010504_only_add_Customer_POST', '010504_只能添加客户表_POST'),
('crm_010505_only_change_Customer_GET', '010505_只能修改客户表_GET'),
('crm_010506_only_change_Customer_POST', '010506_只能修改客户表_POST'),
('crm_010507_only_delete_Customer_GET', '010507_只能删除客户表_GET'),
('crm_010508_only_delete_Customer_POST', '010508_只能删除客户表_POST'), ('crm_010601_only_view_CustomerFollowUp_GET', '010601_只能查看跟进表_GET'),
('crm_010602_only_view_CustomerFollowUp_POST', '010602_只能查看跟进表_POST'),
('crm_010603_only_add_CustomerFollowUp_GET', '010603_只能添加跟进表_GET'),
('crm_010604_only_add_CustomerFollowUp_POST', '010604_只能添加跟进表_POST'),
('crm_010605_only_change_CustomerFollowUp_GET', '010605_只能修改跟进表_GET'),
('crm_010606_only_change_CustomerFollowUp_POST', '010606_只能修改跟进表_POST'),
('crm_010607_only_delete_CustomerFollowUp_GET', '010607_只能删除跟进表_GET'),
('crm_010608_only_delete_CustomerFollowUp_POST', '010608_只能删除跟进表_POST'), ('crm_010701_only_view_Enrollment_GET', '010701_只能查看报名表_GET'),
('crm_010702_only_view_Enrollment_POST', '010702_只能查看报名表_POST'),
('crm_010703_only_add_Enrollment_GET', '010703_只能添加报名表_GET'),
('crm_010704_only_add_Enrollment_POST', '010704_只能添加报名表_POST'),
('crm_010705_only_change_Enrollment_GET', '010705_只能修改报名表_GET'),
('crm_010706_only_change_Enrollment_POST', '010706_只能修改报名表_POST'),
('crm_010707_only_delete_Enrollment_GET', '010707_只能删除报名表_GET'),
('crm_010708_only_delete_Enrollment_POST', '010708_只能删除报名表_POST'), ('crm_010801_only_view_Payment_GET', '010801_只能查看缴费表_GET'),
('crm_010802_only_view_Payment_POST', '010802_只能查看缴费表_POST'),
('crm_010803_only_add_Payment_GET', '010803_只能添加缴费表_GET'),
('crm_010804_only_add_Payment_POST', '010804_只能添加缴费表_POST'),
('crm_010805_only_change_Payment_GET', '010805_只能修改缴费表_GET'),
('crm_010806_only_change_Payment_POST', '010806_只能修改缴费表_POST'),
('crm_010807_only_delete_Payment_GET', '010807_只能删除缴费表_GET'),
('crm_010808_only_delete_Payment_POST', '010808_只能删除缴费表_POST'), ('crm_010901_only_view_CourseRecord_GET', '010901_只能查看上课表_GET'),
('crm_010902_only_view_CourseRecord_POST', '010902_只能查看上课表_POST'),
('crm_010903_only_add_CourseRecord_GET', '010903_只能添加上课表_GET'),
('crm_010904_only_add_CourseRecord_POST', '010904_只能添加上课表_POST'),
('crm_010905_only_change_CourseRecord_GET', '010905_只能修改上课表_GET'),
('crm_010906_only_change_CourseRecord_POST', '010906_只能修改上课表_POST'),
('crm_010907_only_delete_CourseRecord_GET', '010907_只能删除上课表_GET'),
('crm_010908_only_delete_CourseRecord_POST', '010908_只能删除上课表_POST'), ('crm_011001_only_view_StudyRecord_GET', '011001_只能查看学习表_GET'),
('crm_011002_only_view_StudyRecord_POST', '011002_只能查看学习表_POST'),
('crm_011003_only_add_StudyRecord_GET', '011003_只能添加学习表_GET'),
('crm_011004_only_add_StudyRecord_POST', '011004_只能添加学习表_POST'),
('crm_011005_only_change_StudyRecord_GET', '011005_只能修改学习表_GET'),
('crm_011006_only_change_StudyRecord_POST', '011006_只能修改学习表_POST'),
('crm_011007_only_delete_StudyRecord_GET', '011007_只能删除学习表_GET'),
('crm_011008_only_delete_StudyRecord_POST', '011008_只能删除学习表_POST'), ('crm_011101_only_view_UserProfile_GET', '011101_只能查看账号表_GET'),
('crm_011102_only_view_UserProfile_POST', '011102_只能查看账号表_POST'),
('crm_011103_only_add_UserProfile_GET', '011103_只能添加账号表_GET'),
('crm_011104_only_add_UserProfile_POST', '011104_只能添加账号表_POST'),
('crm_011105_only_change_UserProfile_GET', '011105_只能修改账号表_GET'),
('crm_011106_only_change_UserProfile_POST', '011106_只能修改账号表_POST'),
('crm_011107_only_delete_UserProfile_GET', '011107_只能删除账号表_GET'),
('crm_011108_only_delete_UserProfile_POST', '011108_只能删除账号表_POST'), ('crm_011201_only_view_Role_GET', '011201_只能查看角色表_GET'),
('crm_011202_only_view_Role_POST', '011202_只能查看角色表_POST'),
('crm_011203_only_add_Role_GET', '011203_只能添加角色表_GET'),
('crm_011204_only_add_Role_POST', '011204_只能添加角色表_POST'),
('crm_011205_only_change_Role_GET', '011205_只能修改角色表_GET'),
('crm_011206_only_change_Role_POST', '011206_只能修改角色表_POST'),
('crm_011207_only_delete_Role_GET', '011207_只能删除角色表_GET'),
('crm_011208_only_delete_Role_POST', '011208_只能删除角色表_POST'), ('crm_011301_only_view_Tag_GET', '011301_只能查看标签表_GET'),
('crm_011302_only_view_Tag_POST', '011302_只能查看标签表_POST'),
('crm_011303_only_add_Tag_GET', '011303_只能添加标签表_GET'),
('crm_011304_only_add_Tag_POST', '011304_只能添加标签表_POST'),
('crm_011305_only_change_Tag_GET', '011305_只能修改标签表_GET'),
('crm_011306_only_change_Tag_POST', '011306_只能修改标签表_POST'),
('crm_011307_only_delete_Tag_GET', '011307_只能删除标签表_GET'),
('crm_011308_only_delete_Tag_POST', '011308_只能删除标签表_POST'), ('crm_011401_only_view_FirstLayerMenu_GET', '011401_只能查看一层菜单_GET'),
('crm_011402_only_view_FirstLayerMenu_POST', '011402_只能查看一层菜单_POST'),
('crm_011403_only_add_FirstLayerMenu_GET', '011403_只能添加一层菜单_GET'),
('crm_011404_only_add_FirstLayerMenu_POST', '011404_只能添加一层菜单_POST'),
('crm_011405_only_change_FirstLayerMenu_GET', '011405_只能修改一层菜单_GET'),
('crm_011406_only_change_FirstLayerMenu_POST', '011406_只能修改一层菜单_POST'),
('crm_011407_only_delete_FirstLayerMenu_GET', '011407_只能删除一层菜单_GET'),
('crm_011408_only_delete_FirstLayerMenu_POST', '011408_只能删除一层菜单_POST'), ('crm_011501_only_view_SubMenu_GET', '011501_只能查看二层菜单_GET'),
('crm_011502_only_view_SubMenu_POST', '011502_只能查看二层菜单_POST'),
('crm_011503_only_add_SubMenu_GET', '011503_只能添加二层菜单_GET'),
('crm_011504_only_add_SubMenu_POST', '011504_只能添加二层菜单_POST'),
('crm_011505_only_change_SubMenu_GET', '011505_只能修改二层菜单_GET'),
('crm_011506_only_change_SubMenu_POST', '011506_只能修改二层菜单_POST'),
('crm_011507_only_delete_SubMenu_GET', '011507_只能删除二层菜单_GET'),
('crm_011508_only_delete_SubMenu_POST', '011508_只能删除二层菜单_POST'), ('crm_011601_only_view_Groups_GET', '011601_只能查看权限组_GET'),
('crm_011602_only_view_Groups_POST', '011602_只能查看权限组_POST'),
('crm_011603_only_add_Groups_GET', '011603_只能添加权限组_GET'),
('crm_011604_only_add_Groups_POST', '011604_只能添加权限组_POST'),
('crm_011605_only_change_Groups_GET', '011605_只能修改权限组_GET'),
('crm_011606_only_change_Groups_POST', '011606_只能修改权限组_POST'),
('crm_011607_only_delete_Groups_GET', '011607_只能删除权限组_GET'),
('crm_011608_only_delete_Groups_POST', '011608_只能删除权限组_POST'), ('crm_011701_own_password_reset_GET', '011701_自己密码重置_GET'),
('crm_011702_own_password_reset_POST', '011702_自己密码重置_POST'), ('crm_020101_all_not_audit_GET', '020101_销售查看全部的客户未审核_GET'),
('crm_020103_all_enrollment_GET', '020103_销售给全部的客户报名课程_GET'),
('crm_020104_all_enrollment_POST', '020104_销售给全部的客户报名课程_POST'),
('crm_020105_all_contract_review_GET', '020105_销售给全部的客户审核合同_GET'),
('crm_020116_all_contract_review_POST', '020116_销售给全部的客户审核合同_POST'), ('crm_020201_own_enrollment_GET', '020201_销售给自己的客户报名课程_GET'),
('crm_020202_own_enrollment_POST', '020202_销售给自己的客户报名课程_POST'),
('crm_020203_own_contract_review_GET', '020203_销售给自己的客户审核合同_GET'),
('crm_020204_own_contract_review_POST', '020204_销售给自己的客户审核合同_POST'), ('crm_030101_all_not_payment_GET', '030101_财务查看全部的客户未缴费_GET'),
('crm_030102_all_not_payment_POST', '030102_财务查看全部的客户未缴费_POST'),
('crm_030103_all_already_payment_GET', '030103_财务查看全部的客户已缴费_GET'),
('crm_030104_all_already_payment_POST', '030104_财务查看全部的客户已缴费_POST'),
('crm_030105_all_payment_GET', '030105_财务进行全部的客户缴费_GET'),
('crm_030106_all_payment_POST', '030106_财务进行全部的客户缴费_POST'), ('crm_040101_own_student_course_GET', '040101_学生查看自己的课程_GET'),
('crm_040102_own_student_course_POST', '040102_学生查看自己的课程_POST'),
('crm_040103_own_studyrecords_GET', '040103_学生自己的上课记录_GET'),
('crm_040104_own_studyrecords_POST', '040104_学生自己的上课记录_POST'),
('crm_040105_own_homework_detail_GET', '040105_学生自己的作业详情_GET'),
('crm_040106_own_homework_detail_POST', '040106_学生自己的作业详情_POST'), ('crm_050101_own_teacher_class_GET', '050101_讲师查看自己的班级_GET'),
('crm_050102_own_teacher_class_POST', '050102_讲师查看自己的班级_POST'),
('crm_050103_own_teacher_class_detail_GET', '050103_讲师查看自己的课节详情_GET'),
('crm_050104_own_teacher_class_detail_POST', '050104_讲师查看自己的课节详情_POST'),
('crm_050105_own_teacher_lesson_detail_GET', '050105_讲师查看自己的课节学员_GET'),
('crm_050106_own_teacher_lesson_detail_POST', '050106_讲师查看自己的课节学员_POST'),
('crm_050107_own_howk_down_GET', '050107_讲师自己的学员作业下载_GET'),
('crm_050108_own_howk_down_POST', '050108_讲师自己的学员作业下载_POST'), ('crm_060101_own_coursetop_details_GET', '060101_讲师查看自己的班级排名详情_GET'),
('crm_060102_own_coursetop_details_POST', '060102_讲师查看自己的班级排名详情_POST'),
('crm_060103_own_coursetop_score_GET', '060103_讲师查看自己的班级分数排行_GET'),
('crm_060104_own_coursetop_score_POST', '060104_讲师查看自己的班级排分数排行_POST'),
('crm_060105_own_coursetop_homework_GET', '060105_讲师查看自己的班级作业排行_GET'),
('crm_060106_own_coursetop_homework_POST', '060106_讲师查看自己的班级作业排行_POST'),
('crm_060107_own_coursetop_attendance_GET', '060107_讲师查看自己的班级出勤排行_GET'),
('crm_060108_own_coursetop_attendance_POST', '060108_讲师查看自己的班级出勤排行_POST'), )
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————
"""15权限组"""
from django.contrib.auth.models import Group
class Groups(Group):
class Meta:
verbose_name_plural = '15权限组'
# ————————74PerfectCRM实现CRM权限和权限组限制URL———————— """11角色表"""
class Role(models.Model):
name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节 # ————————72PerfectCRM实现CRM动态菜单和角色————————
menus = models.ManyToManyField('FirstLayerMenu',verbose_name='一层菜单',blank=True)
# ————————72PerfectCRM实现CRM动态菜单和角色———————— 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———————— # ————————72PerfectCRM实现CRM动态菜单和角色————————
"""13一层菜单名"""
class FirstLayerMenu(models.Model):
'''第一层侧边栏菜单'''
name = models.CharField('一层菜单名',max_length=64)
url_type_choices = ((0,'相关的名字'),(1,'固定的URL'))
url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
url_name = models.CharField(max_length=64,verbose_name='一层菜单路径')
order = models.SmallIntegerField(default=0,verbose_name='菜单排序')
sub_menus = models.ManyToManyField('SubMenu',blank=True) def __str__(self):
return self.name class Meta:
verbose_name_plural = "13第一层菜单" """14二层菜单名"""
class SubMenu(models.Model):
'''第二层侧边栏菜单'''
name = models.CharField('二层菜单名', max_length=64)
url_type_choices = ((0,'相关的名字'),(1,'固定的URL'))
url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
url_name = models.CharField(max_length=64, verbose_name='二层菜单路径')
order = models.SmallIntegerField(default=0, verbose_name='菜单排序') def __str__(self):
return self.name class Meta:
verbose_name_plural = "14第二层菜单"
# ————————72PerfectCRM实现CRM动态菜单和角色————————

#models.py

 # permission_list.py
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————
from permissions import CJ # 自定义权限钩子 # 权限样式 app_权限名字
perm_dic = { 'crm_010101_all_table_data_list_GET': ['table_data_list', 'GET', [], {}, ],
# ('crm_010101_all_table_data_list_GET', '010101_全部查看数据_GET'),
'crm_010102_all_table_data_list_POST': ['table_data_list', 'POST', [], {}, ],
# ('crm_010102_all_table_data_list_POST', '010102_查全部看数据_POST'),
'crm_010103_all_table_add_GET': ['table_add', 'GET', [], {}, ],
# ('crm_010103_all_table_add_GET', '010103_全部添加数据_GET'),
'crm_010104_all_table_add_POST': ['table_add', 'POST', [], {}, ],
# ('crm_010104_all_table_add_POST', '010104_全部添加数据_POST'),
'crm_010105_all_table_change_GET': ['table_change', 'GET', [], {}, ],
# ('crm_010105_all_table_change_GET', '010105_全部修改数据_GET'),
'crm_010106_all_table_change_POST': ['table_change', 'POST', [], {}, ],
# ('crm_010106_all_table_change_POST', '010106_全部修改数据_POST'),
'crm_010107_all_table_delete_GET': ['table_delete', 'GET', [], {}, ],
# ('crm_010107_all_table_delete_GET', '010107_全部删除数据_GET'),
'crm_010108_all_table_delete_POST': ['table_delete', 'POST', [], {}, ],
# ('crm_010108_all_table_delete_POST', '010108_全部删除数据_POST'),
'crm_010109_all_password_reset_GET': ['password_reset', 'GET', [], {}, ],
# ('crm_010109_all_password_reset_GET', '010109_全部密码重置_GET'),
'crm_010110_all_password_reset_POST': ['password_reset', 'POST', [], {}, ],
# ('crm_010110_all_password_reset_POST', '010110_全部密码重置_POST'), 'crm_010201_only_view_Branch_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Branch],
# ('crm_010201_only_view_Branch_GET', '010201_只能查看校区表_GET'),
'crm_010202_only_view_Branch_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Branch],
# ('crm_010202_only_view_Branch_POST', '010202_只能查看校区表_POST'),
'crm_010203_only_add_Branch_GET': ['table_add', 'GET', [], {}, CJ.JM_Branch],
# ('crm_010203_only_add_Branch_GET', '010203_只能添加校区表_GET'),
'crm_010204_only_add_Branch_POST': ['table_add', 'POST', [], {}, CJ.JM_Branch],
# ('crm_010204_only_add_Branch_POST', '010204_只能添加校区表_POST'),
'crm_010205_only_change_Branch_GET': ['table_change', 'GET', [], {}, CJ.JM_Branch],
# ('crm_010205_only_change_Branch_GET', '010205_只能修改校区表_GET'),
'crm_010206_only_change_Branch_POST': ['table_change', 'POST', [], {}, CJ.JM_Branch],
# ('crm_010206_only_change_Branch_POST', '010206_只能修改校区表_POST'),
'crm_010207_only_delete_Branch_GET': ['table_delete', 'GET', [], {}, CJ.JM_Branch],
# ('crm_010207_only_delete_Branch_GET', '010207_只能删除校区表_GET'),
'crm_010208_only_delete_Branch_POST': ['table_delete', 'POST', [], {}, CJ.JM_Branch],
# ('crm_010208_only_delete_Branch_POST', '010208_只能删除校区表_POST'), 'crm_010301_only_view_ClassList_GET': ['table_data_list', 'GET', [], {}, CJ.JM_ClassList],
# ('crm_010301_only_view_ClassList_GET', '010301_只能查看班级表_GET'),
'crm_010302_only_view_ClassList_POST': ['table_data_list', 'POST', [], {}, CJ.JM_ClassList],
# ('crm_010302_only_view_ClassList_POST', '010302_只能查看班级表_POST'),
'crm_010303_only_add_ClassList_GET': ['table_add', 'GET', [], {}, CJ.JM_ClassList],
# ('crm_010303_only_add_ClassList_GET', '010303_只能添加班级表_GET'),
'crm_010304_only_add_ClassList_POST': ['table_add', 'POST', [], {}, CJ.JM_ClassList],
# ('crm_010304_only_add_ClassList_POST', '010304_只能添加班级表_POST'),
'crm_010305_only_change_ClassList_GET': ['table_change', 'GET', [], {}, CJ.JM_ClassList],
# ('crm_010305_only_change_ClassList_GET', '010305_只能修改班级表_GET'),
'crm_010306_only_change_ClassList_POST': ['table_change', 'POST', [], {}, CJ.JM_ClassList],
# ('crm_010306_only_change_ClassList_POST', '010306_只能修改班级表_POST'),
'crm_010307_only_delete_ClassList_GET': ['table_delete', 'GET', [], {}, CJ.JM_ClassList],
# ('crm_010307_only_delete_ClassList_GET', '010307_只能删除班级表_GET'),
'crm_010308_only_delete_ClassList_POST': ['table_delete', 'POST', [], {}, CJ.JM_ClassList],
# ('crm_010308_only_delete_ClassList_POST', '010308_只能删除班级表_POST'), 'crm_010401_only_view_Course_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Course],
# ('crm_010401_only_view_Course_GET', '010401_只能查看课程表_GET'),
'crm_010402_only_view_Course_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Course],
# ('crm_010402_only_view_Course_POST', '010402_只能查看课程表_POST'),
'crm_010403_only_add_Course_GET': ['table_add', 'GET', [], {}, CJ.JM_Course],
# ('crm_010403_only_add_Course_GET', '010403_只能添加课程表_GET'),
'crm_010404_only_add_Course_POST': ['table_add', 'POST', [], {}, CJ.JM_Course],
# ('crm_010404_only_add_Course_POST', '010404_只能添加课程表_POST'),
'crm_010405_only_change_Course_GET': ['table_change', 'GET', [], {}, CJ.JM_Course],
# ('crm_010405_only_change_Course_GET', '010405_只能修改课程表_GET'),
'crm_010406_only_change_Course_POST': ['table_change', 'POST', [], {}, CJ.JM_Course],
# ('crm_010406_only_change_Course_POST', '010406_只能修改课程表_POST'),
'crm_010407_only_delete_Course_GET': ['table_delete', 'GET', [], {}, CJ.JM_Course],
# ('crm_010407_only_delete_Course_GET', '010407_只能删除课程表_GET'),
'crm_010408_only_delete_Course_POST': ['table_delete', 'POST', [], {}, CJ.JM_Course],
# ('crm_010408_only_delete_Course_POST', '010408_只能删除课程表_POST'), 'crm_010501_only_view_Customer_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Customer],
# ('crm_010501_only_view_Customer_GET', '010501_只能查看客户表_GET'),
'crm_010502_only_view_Customer_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Customer],
# ('crm_010502_only_view_Customer_POST', '010502_只能查看客户表_POST'),
'crm_010503_only_add_Customer_GET': ['table_add', 'GET', [], {}, CJ.JM_Customer],
# ('crm_010503_only_add_Customer_GET', '010503_只能添加客户表_GET'),
'crm_010504_only_add_Customer_POST': ['table_add', 'POST', [], {}, CJ.JM_Customer],
# ('crm_010504_only_add_Customer_POST', '010504_只能添加客户表_POST'),
'crm_010505_only_change_Customer_GET': ['table_change', 'GET', [], {}, CJ.JM_Customer],
# ('crm_010505_only_change_Customer_GET', '010505_只能修改客户表_GET'),
'crm_010506_only_change_Customer_POST': ['table_change', 'POST', [], {}, CJ.JM_Customer],
# ('crm_010506_only_change_Customer_POST', '010506_只能修改客户表_POST'),
'crm_010507_only_delete_Customer_GET': ['table_delete', 'GET', [], {}, CJ.JM_Customer],
# ('crm_010507_only_delete_Customer_GET', '010507_只能删除客户表_GET'),
'crm_010508_only_delete_Customer_POST': ['table_delete', 'POST', [], {}, CJ.JM_Customer],
# ('crm_010508_only_delete_Customer_POST', '010508_只能删除客户表_POST'), 'crm_010601_only_view_CustomerFollowUp_GET': ['table_data_list', 'GET', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010601_only_view_CustomerFollowUp_GET', '010601_只能查看跟进表_GET'),
'crm_010602_only_view_CustomerFollowUp_POST': ['table_data_list', 'POST', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010602_only_view_CustomerFollowUp_POST', '010602_只能查看跟进表_POST'),
'crm_010603_only_add_CustomerFollowUp_GET': ['table_add', 'GET', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010603_only_add_CustomerFollowUp_GET', '010603_只能添加跟进表_GET'),
'crm_010604_only_add_CustomerFollowUp_POST': ['table_add', 'POST', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010604_only_add_CustomerFollowUp_POST', '010604_只能添加跟进表_POST'),
'crm_010605_only_change_CustomerFollowUp_GET': ['table_change', 'GET', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010605_only_change_CustomerFollowUp_GET', '010605_只能修改跟进表_GET'),
'crm_010606_only_change_CustomerFollowUp_POST': ['table_change', 'POST', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010606_only_change_CustomerFollowUp_POST', '010606_只能修改跟进表_POST'),
'crm_010607_only_delete_CustomerFollowUp_GET': ['table_delete', 'GET', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010607_only_delete_CustomerFollowUp_GET', '010607_只能删除跟进表_GET'),
'crm_010608_only_delete_CustomerFollowUp_POST': ['table_delete', 'POST', [], {}, CJ.JM_CustomerFollowUp],
# ('crm_010608_only_delete_CustomerFollowUp_POST', '010608_只能删除跟进表_POST'), 'crm_010701_only_view_Enrollment_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Enrollment],
# ('crm_010701_only_view_Enrollment_GET', '010701_只能查看报名表_GET'),
'crm_010702_only_view_Enrollment_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Enrollment],
# ('crm_010702_only_view_Enrollment_POST', '010702_只能查看报名表_POST'),
'crm_010703_only_add_Enrollment_GET': ['table_add', 'GET', [], {}, CJ.JM_Enrollment],
# ('crm_010703_only_add_Enrollment_GET', '010703_只能添加报名表_GET'),
'crm_010704_only_add_Enrollment_POST': ['table_add', 'POST', [], {}, CJ.JM_Enrollment],
# ('crm_010704_only_add_Enrollment_POST', '010704_只能添加报名表_POST'),
'crm_010705_only_change_Enrollment_GET': ['table_change', 'GET', [], {}, CJ.JM_Enrollment],
# ('crm_010705_only_change_Enrollment_GET', '010705_只能修改报名表_GET'),
'crm_010706_only_change_Enrollment_POST': ['table_change', 'POST', [], {}, CJ.JM_Enrollment],
# ('crm_010706_only_change_Enrollment_POST', '010706_只能修改报名表_POST'),
'crm_010707_only_delete_Enrollment_GET': ['table_delete', 'GET', [], {}, CJ.JM_Enrollment],
# ('crm_010707_only_delete_Enrollment_GET', '010707_只能删除报名表_GET'),
'crm_010708_only_delete_Enrollment_POST': ['table_delete', 'POST', [], {}, CJ.JM_Enrollment],
# ('crm_010708_only_delete_Enrollment_POST', '010708_只能删除报名表_POST'), 'crm_010801_only_view_Payment_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Payment],
# ('crm_010801_only_view_Payment_GET', '010801_只能查看缴费表_GET'),
'crm_010802_only_view_Payment_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Payment],
# ('crm_010802_only_view_Payment_POST', '010802_只能查看缴费表_POST'),
'crm_010803_only_add_Payment_GET': ['table_add', 'GET', [], {}, CJ.JM_Payment],
# ('crm_010803_only_add_Payment_GET', '010803_只能添加缴费表_GET'),
'crm_010804_only_add_Payment_POST': ['table_add', 'POST', [], {}, CJ.JM_Payment],
# ('crm_010804_only_add_Payment_POST', '010804_只能添加缴费表_POST'),
'crm_010805_only_change_Payment_GET': ['table_change', 'GET', [], {}, CJ.JM_Payment],
# ('crm_010805_only_change_Payment_GET', '010805_只能修改缴费表_GET'),
'crm_010806_only_change_Payment_POST': ['table_change', 'POST', [], {}, CJ.JM_Payment],
# ('crm_010806_only_change_Payment_POST', '010806_只能修改缴费表_POST'),
'crm_010807_only_delete_Payment_GET': ['table_delete', 'GET', [], {}, CJ.JM_Payment],
# ('crm_010807_only_delete_Payment_GET', '010807_只能删除缴费表_GET'),
'crm_010808_only_delete_Payment_POST': ['table_delete', 'POST', [], {}, CJ.JM_Payment],
# ('crm_010808_only_delete_Payment_POST', '010808_只能删除缴费表_POST'), 'crm_010901_only_view_CourseRecord_GET': ['table_data_list', 'GET', [], {}, CJ.JM_CourseRecord],
# ('crm_010901_only_view_CourseRecord_GET', '010901_只能查看上课表_GET'),
'crm_010902_only_view_CourseRecord_POST': ['table_data_list', 'POST', [], {}, CJ.JM_CourseRecord],
# ('crm_010902_only_view_CourseRecord_POST', '010902_只能查看上课表_POST'),
'crm_010903_only_add_CourseRecord_GET': ['table_add', 'GET', [], {}, CJ.JM_CourseRecord],
# ('crm_010903_only_add_CourseRecord_GET', '010903_只能添加上课表_GET'),
'crm_010904_only_add_CourseRecord_POST': ['table_add', 'POST', [], {}, CJ.JM_CourseRecord],
# ('crm_010904_only_add_CourseRecord_POST', '010904_只能添加上课表_POST'),
'crm_010905_only_change_CourseRecord_GET': ['table_change', 'GET', [], {}, CJ.JM_CourseRecord],
# ('crm_010905_only_change_CourseRecord_GET', '010905_只能修改上课表_GET'),
'crm_010906_only_change_CourseRecord_POST': ['table_change', 'POST', [], {}, CJ.JM_CourseRecord],
# ('crm_010906_only_change_CourseRecord_POST', '010906_只能修改上课表_POST'),
'crm_010907_only_delete_CourseRecord_GET': ['table_delete', 'GET', [], {}, CJ.JM_CourseRecord],
# ('crm_010907_only_delete_CourseRecord_GET', '010907_只能删除上课表_GET'),
'crm_010908_only_delete_CourseRecord_POST': ['table_delete', 'POST', [], {}, CJ.JM_CourseRecord],
# ('crm_010908_only_delete_CourseRecord_POST', '010908_只能删除上课表_POST'), 'crm_011001_only_view_StudyRecord_GET': ['table_data_list', 'GET', [], {}, CJ.JM_StudyRecord],
# ('crm_011001_only_view_StudyRecord_GET', '011001_只能查看学习表_GET'),
'crm_011002_only_view_StudyRecord_POST': ['table_data_list', 'POST', [], {}, CJ.JM_StudyRecord],
# ('crm_011002_only_view_StudyRecord_POST', '011002_只能查看学习表_POST'),
'crm_011003_only_add_StudyRecord_GET': ['table_add', 'GET', [], {}, CJ.JM_StudyRecord],
# ('crm_011003_only_add_StudyRecord_GET', '011003_只能添加学习表_GET'),
'crm_011004_only_add_StudyRecord_POST': ['table_add', 'POST', [], {}, CJ.JM_StudyRecord],
# ('crm_011004_only_add_StudyRecord_POST', '011004_只能添加学习表_POST'),
'crm_011005_only_change_StudyRecord_GET': ['table_change', 'GET', [], {}, CJ.JM_StudyRecord],
# ('crm_011005_only_change_StudyRecord_GET', '011005_只能修改学习表_GET'),
'crm_011006_only_change_StudyRecord_POST': ['table_change', 'POST', [], {}, CJ.JM_StudyRecord],
# ('crm_011006_only_change_StudyRecord_POST', '011006_只能修改学习表_POST'),
'crm_011007_only_delete_StudyRecord_GET': ['table_delete', 'GET', [], {}, CJ.JM_StudyRecord],
# ('crm_011007_only_delete_StudyRecord_GET', '011007_只能删除学习表_GET'),
'crm_011008_only_delete_StudyRecord_POST': ['table_delete', 'POST', [], {}, CJ.JM_StudyRecord],
# ('crm_011008_only_delete_StudyRecord_POST', '011008_只能删除学习表_POST'), 'crm_011101_only_view_UserProfile_GET': ['table_data_list', 'GET', [], {}, CJ.JM_UserProfile],
# ('crm_011101_only_view_UserProfile_GET', '011101_只能查看账号表_GET'),
'crm_011102_only_view_UserProfile_POST': ['table_data_list', 'POST', [], {}, CJ.JM_UserProfile],
# ('crm_011102_only_view_UserProfile_POST', '011102_只能查看账号表_POST'),
'crm_011103_only_add_UserProfile_GET': ['table_add', 'GET', [], {}, CJ.JM_UserProfile],
# ('crm_011103_only_add_UserProfile_GET', '011103_只能添加账号表_GET'),
'crm_011104_only_add_UserProfile_POST': ['table_add', 'POST', [], {}, CJ.JM_UserProfile],
# ('crm_011104_only_add_UserProfile_POST', '011104_只能添加账号表_POST'),
'crm_011105_only_change_UserProfile_GET': ['table_change', 'GET', [], {}, CJ.JM_UserProfile],
# ('crm_011105_only_change_UserProfile_GET', '011105_只能修改账号表_GET'),
'crm_011106_only_change_UserProfile_POST': ['table_change', 'POST', [], {}, CJ.JM_UserProfile],
# ('crm_011106_only_change_UserProfile_POST', '011106_只能修改账号表_POST'),
'crm_011107_only_delete_UserProfile_GET': ['table_delete', 'GET', [], {}, CJ.JM_UserProfile],
# ('crm_011107_only_delete_UserProfile_GET', '011107_只能删除账号表_GET'),
'crm_011108_only_delete_UserProfile_POST': ['table_delete', 'POST', [], {}, CJ.JM_UserProfile],
# ('crm_011108_only_delete_UserProfile_POST', '011108_只能删除账号表_POST'), 'crm_011201_only_view_Role_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Role],
# ('crm_011201_only_view_Role_GET', '011201_只能查看角色表_GET'),
'crm_011202_only_view_Role_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Role],
# ('crm_011202_only_view_Role_POST', '011202_只能查看角色表_POST'),
'crm_011203_only_add_Role_GET': ['table_add', 'GET', [], {}, CJ.JM_Role],
# ('crm_011203_only_add_Role_GET', '011203_只能添加角色表_GET'),
'crm_011204_only_add_Role_POST': ['table_add', 'POST', [], {}, CJ.JM_Role],
# ('crm_011204_only_add_Role_POST', '011204_只能添加角色表_POST'),
'crm_011205_only_change_Role_GET': ['table_change', 'GET', [], {}, CJ.JM_Role],
# ('crm_011205_only_change_Role_GET', '011205_只能修改角色表_GET'),
'crm_011206_only_change_Role_POST': ['table_change', 'POST', [], {}, CJ.JM_Role],
# ('crm_011206_only_change_Role_POST', '011206_只能修改角色表_POST'),
'crm_011207_only_delete_Role_GET': ['table_delete', 'GET', [], {}, CJ.JM_Role],
# ('crm_011207_only_delete_Role_GET', '011207_只能删除角色表_GET'),
'crm_011208_only_delete_Role_POST': ['table_delete', 'POST', [], {}, CJ.JM_Role],
# ('crm_011208_only_delete_Role_POST', '011208_只能删除角色表_POST'), 'crm_011301_only_view_Tag_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Tag],
# ('crm_011301_only_view_Tag_GET', '011301_只能查看标签表_GET'),
'crm_011302_only_view_Tag_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Tag],
# ('crm_011302_only_view_Tag_POST', '011302_只能查看标签表_POST'),
'crm_011303_only_add_Tag_GET': ['table_add', 'GET', [], {}, CJ.JM_Tag],
# ('crm_011303_only_add_Tag_GET', '011303_只能添加标签表_GET'),
'crm_011304_only_add_Tag_POST': ['table_add', 'POST', [], {}, CJ.JM_Tag],
# ('crm_011304_only_add_Tag_POST', '011304_只能添加标签表_POST'),
'crm_011305_only_change_Tag_GET': ['table_change', 'GET', [], {}, CJ.JM_Tag],
# (('crm_011305_only_change_Tag_GET', '011305_只能修改标签表_GET')
'crm_011306_only_change_Tag_POST': ['table_change', 'POST', [], {}, CJ.JM_Tag],
# ('crm_011306_only_change_Tag_POST', '011306_只能修改标签表_POST'),
'crm_011307_only_delete_Tag_GET': ['table_delete', 'GET', [], {}, CJ.JM_Tag],
# ('crm_011307_only_delete_Tag_GET', '011307_只能删除标签表_GET'),
'crm_011308_only_delete_Tag_POST': ['table_delete', 'POST', [], {}, CJ.JM_Tag],
# ('crm_011308_only_delete_Tag_POST', '011308_只能删除标签表_POST'), 'crm_011401_only_view_FirstLayerMenu_GET': ['table_data_list', 'GET', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011401_only_view_FirstLayerMenu_GET', '011401_只能查看一层菜单_GET'),
'crm_011402_only_view_FirstLayerMenu_POST': ['table_data_list', 'POST', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011402_only_view_FirstLayerMenu_POST', '011402_只能查看一层菜单_POST'),
'crm_011403_only_add_FirstLayerMenu_GET': ['table_add', 'GET', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011403_only_add_FirstLayerMenu_GET', '011403_只能添加一层菜单_GET'),
'crm_011404_only_add_FirstLayerMenu_POST': ['table_add', 'POST', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011404_only_add_FirstLayerMenu_POST', '011404_只能添加一层菜单_POST'),
'crm_011405_only_change_FirstLayerMenu_GET': ['table_change', 'GET', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011405_only_change_FirstLayerMenu_GET', '011405_只能修改一层菜单_GET'),
'crm_011406_only_change_FirstLayerMenu_POST': ['table_change', 'POST', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011406_only_change_FirstLayerMenu_POST', '011406_只能修改一层菜单_POST'),
'crm_011407_only_delete_FirstLayerMenu_GET': ['table_delete', 'GET', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011407_only_delete_FirstLayerMenu_GET', '011407_只能删除一层菜单_GET'),
'crm_011408_only_delete_FirstLayerMenu_POST': ['table_delete', 'POST', [], {}, CJ.JM_FirstLayerMenu],
# ('crm_011408_only_delete_FirstLayerMenu_POST', '011408_只能删除一层菜单_POST'), 'crm_011501_only_view_SubMenu_GET': ['table_data_list', 'GET', [], {}, CJ.JM_SubMenu],
# ('crm_011501_only_view_SubMenu_GET', '011501_只能查看二层菜单_GET'),
'crm_011502_only_view_SubMenu_POST': ['table_data_list', 'POST', [], {}, CJ.JM_SubMenu],
# ('crm_011502_only_view_SubMenu_POST', '011502_只能查看二层菜单_POST'),
'crm_011503_only_add_SubMenu_GET': ['table_add', 'GET', [], {}, CJ.JM_SubMenu],
# ('crm_011503_only_add_SubMenu_GET', '011503_只能添加二层菜单_GET'),
'crm_011504_only_add_SubMenu_POST': ['table_add', 'POST', [], {}, CJ.JM_SubMenu],
# ('crm_011504_only_add_SubMenu_POST', '011504_只能添加二层菜单_POST'),
'crm_011505_only_change_SubMenu_GET': ['table_change', 'GET', [], {}, CJ.JM_SubMenu],
# ('crm_011505_only_change_SubMenu_GET', '011505_只能修改二层菜单_GET'),
'crm_011506_only_change_SubMenu_POST': ['table_change', 'POST', [], {}, CJ.JM_SubMenu],
# ('crm_011506_only_change_SubMenu_POST', '011506_只能修改二层菜单_POST'),
'crm_011507_only_delete_SubMenu_GET': ['table_delete', 'GET', [], {}, CJ.JM_SubMenu],
# ('crm_011507_only_delete_SubMenu_GET', '011507_只能删除二层菜单_GET'),
'crm_011508_only_delete_SubMenu_POST': ['table_delete', 'POST', [], {}, CJ.JM_SubMenu],
# ('crm_011508_only_delete_SubMenu_POST', '011508_只能删除二层菜单_POST'), 'crm_011601_only_view_Groups_GET': ['table_data_list', 'GET', [], {}, CJ.JM_Groups],
# ('crm_011601_only_view_Groups_GET', '011601_只能查看权限组_GET'),
'crm_011602_only_view_Groups_POST': ['table_data_list', 'POST', [], {}, CJ.JM_Groups],
# ('crm_011602_only_view_Groups_POST', '011602_只能查看权限组_POST'),
'crm_011603_only_add_Groups_GET': ['table_add', 'GET', [], {}, CJ.JM_Groups],
# ('crm_011603_only_add_Groups_GET', '011603_只能添加权限组_GET'),
'crm_011604_only_add_Groups_POST': ['table_add', 'POST', [], {}, CJ.JM_Groups],
# ('crm_011604_only_add_Groups_POST', '011604_只能添加权限组_POST'),
'crm_011605_only_change_Groups_GET': ['table_change', 'GET', [], {}, CJ.JM_Groups],
# ('crm_011605_only_change_Groups_GET', '011605_只能修改权限组_GET'),
'crm_011606_only_change_Groups_POST': ['table_change', 'POST', [], {}, CJ.JM_Groups],
# ('crm_011606_only_change_Groups_POST', '011606_只能修改权限组_POST'),
'crm_011607_only_delete_Groups_GET': ['table_delete', 'GET', [], {}, CJ.JM_Groups],
# ('crm_011607_only_delete_Groups_GET', '011607_只能删除权限组_GET'),
'crm_011608_only_delete_Groups_POST': ['table_delete', 'POST', [], {}, CJ.JM_Groups],
# ('crm_011608_only_delete_Groups_POST', '011608_只能删除权限组_POST'), 'crm_011701_own_password_reset_GET': ['password_reset', 'GET', [], {}, CJ.own_password_reset],
# ('crm_011701_own_password_reset_GET', '011701_自己密码重置_GET'),
'crm_011702_own_password_reset_POST': ['password_reset', 'POST', [], {}, CJ.own_password_reset],
# ('crm_011702_own_password_reset_POST', '011702_自己密码重置_POST'), 'crm_020101_all_not_audit_GET': ['not_audit', 'GET', [], {}, ],
# ('crm_020101_all_not_audit_GET', '020101_销售查看全部的客户未审核_GET'),
'crm_020103_all_enrollment_GET': ['enrollment', 'GET', [], {}, ],
# ('crm_020103_all_enrollment_GET', '020103_销售给全部的客户报名课程_GET'),
'crm_020104_all_enrollment_POST': ['enrollment', 'POST', [], {}, ],
# ('crm_020104_all_enrollment_POST', '020104_销售给全部的客户报名课程_POST'),
'crm_020105_all_contract_review_GET': ['contract_review', 'GET', [], {}, ],
# ('crm_020105_all_contract_review_GET', '020105_销售给全部的客户审核合同_GET'),
'crm_020116_all_contract_review_POST': ['contract_review', 'POST', [], {}, ],
# ('crm_020116_all_contract_review_POST', '020116_销售给全部的客户审核合同_POST'), 'crm_020201_own_enrollment_GET': ['enrollment', 'GET', [], {}, CJ.own_enrollment],
# ('crm_020201_own_enrollment_GET', '020201_销售给自己的客户报名课程_GET'),
'crm_020202_own_enrollment_POST': ['enrollment', 'POST', [], {}, CJ.own_enrollment],
# ('crm_020202_own_enrollment_POST', '020202_销售给自己的客户报名课程_POST'),
'crm_020203_own_contract_review_GET': ['contract_review', 'GET', [], {}, CJ.own_contract_review],
# ('crm_020203_own_contract_review_GET', '020203_销售给自己的客户审核合同_GET'),
'crm_020204_own_contract_review_POST': ['contract_review', 'POST', [], {}, CJ.own_contract_review],
# ('crm_020204_own_contract_review_POST', '020204_销售给自己的客户审核合同_POST'), 'crm_030101_all_not_payment_GET': ['not_payment', 'GET', [], {}, ],
# ('crm_030101_all_not_payment_GET', '030101_财务查看全部的客户未缴费_GET'),
'crm_030102_all_not_payment_POST': ['not_payment', 'GET', [], {}, ],
# ('crm_030102_all_not_payment_POST', '030102_财务查看全部的客户未缴费_POST'),
'crm_030103_all_already_payment_GET': ['already_payment', 'GET', [], {}, ],
# ('crm_030103_all_already_payment_GET', '030103_财务查看全部的客户已缴费_GET'),
'crm_030104_all_already_payment_POST': ['already_payment', 'GET', [], {}, ],
# ('crm_030104_all_already_payment_POST', '030104_财务查看全部的客户已缴费_POST'),
'crm_030105_all_payment_GET': ['payment', 'GET', [], {}, ],
# ('crm_030105_all_payment_GET', '030105_财务进行全部的客户缴费_GET'),
'crm_030106_all_payment_POST': ['payment', 'POST', [], {}, ],
# ('crm_030106_all_payment_POST', '030106_财务进行全部的客户缴费_POST'), 'crm_040101_own_student_course_GET': ['student_course', 'GET', [], {}, ],
# ('crm_040101_own_student_course_GET', '040101_学生查看自己的课程_GET'),
'crm_040102_own_student_course_POST': ['student_course', 'POST', [], {}, ],
# ('crm_040102_own_student_course_POST', '040102_学生查看自己的课程_POST'),
'crm_040103_own_studyrecords_GET': ['studyrecords', 'GET', [], {}, CJ.own_studyrecords],
# ('crm_040103_own_studyrecords_GET', '040103_学生自己的上课记录_GET'),
'crm_040104_own_studyrecords_POST': ['studyrecords', 'POST', [], {}, CJ.own_studyrecords],
# ('crm_050104_own_studyrecords_POST', '040104_学生自己的上课记录_POST'),
'crm_040105_own_homework_detail_GET': ['homework_detail', 'GET', [], {}, CJ.own_homework_detail],
# ('crm_040105_own_homework_detail_GET', '040105_学生自己的作业详情_GET'),
'crm_040106_own_homework_detail_POST': ['homework_detail', 'POST', [], {}, CJ.own_homework_detail],
# ('crm_040106_own_homework_detail_POST', '040106_学生自己的作业详情_POST'), 'crm_050101_own_teacher_class_GET': ['teacher_class', 'GET', [], {}, ],
# ('crm_050101_own_teacher_class_GET', '050101_讲师查看自己的班级_GET'),
'crm_05102_own_teacher_class_POST': ['teacher_class', 'POST', [], {}, ],
# ('crm_050102_own_teacher_class_POST', '050102_讲师查看自己的班级_POST'),
'crm_050103_own_teacher_class_detail_GET': ['teacher_class_detail', 'GET', [], {}, CJ.own_teacher_class_detail],
# ('crm_050103_own_teacher_class_detail_GET', '050103_讲师查看自己的课节详情_GET'),
'crm_050104_own_teacher_class_detail_POST': ['teacher_class_detail', 'POST', [], {}, CJ.own_teacher_class_detail],
# ('crm_050104_own_teacher_class_detail_POST', '050104_讲师查看自己的课节详情_POST'),
'crm_050105_own_teacher_lesson_detail_GET': ['teacher_lesson_detail', 'GET', [], {}, CJ.own_teacher_lesson_detail],
# ('crm_050105_own_teacher_lesson_detail_GET', '050105_讲师查看自己的课节学员_GET'),
'crm_050106_own_teacher_lesson_detail_POST': ['teacher_lesson_detail', 'POST', [], {}, CJ.own_teacher_lesson_detail],
# ('crm_050106_own_teacher_lesson_detail_POST', '050106_讲师查看自己的课节学员_POST'),
'crm_050107_own_howk_down_GET': ['howk_down', 'GET', [], {}, CJ.own_howk_down],
# ('crm_050107_own_howk_down_GET', '050107_讲师自己的学员作业下载_GET'),
'crm_050108_own_howk_down_POST': ['howk_down', 'POST', [], {}, CJ.own_howk_down],
# ('crm_050108_own_howk_down_POST', '050108_讲师自己的学员作业下载_POST'), 'crm_060101_own_coursetop_details_GET': ['coursetop_details', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060101_own_coursetop_details_GET', '060101_讲师查看自己的班级排名详情_GET'),
'crm_060102_own_coursetop_details_POST': ['coursetop_details', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060102_own_coursetop_details_POST', '060102_讲师查看自己的班级排名详情_POST'),
'crm_060103_own_coursetop_score_GET': ['coursetop_score', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060103_own_coursetop_score_GET', '060103_讲师查看自己的班级分数排行_GET'),
'crm_060104_own_coursetop_score_POST': ['coursetop_score', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060104_own_coursetop_score_POST', '060104_讲师查看自己的班级排分数排行_POST'),
'crm_060105_own_coursetop_homework_GET': ['coursetop_homework', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060105_own_coursetop_homework_GET', '060105_讲师查看自己的班级作业排行_GET'),
'crm_060106_own_coursetop_homework_POST': ['coursetop_homework', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060106_own_coursetop_homework_POST', '060106_讲师查看自己的班级作业排行_POST'),
'crm_060107_own_coursetop_attendance_GET': ['coursetop_attendance', 'GET', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060107_own_coursetop_attendance_GET', '060107_讲师查看自己的班级出勤排行_GET'),
'crm_060108_own_coursetop_attendance_POST': ['coursetop_attendance', 'POST', [], {}, CJ.JM_crm_classlist_teachers],
# ('crm_060108_own_coursetop_attendance_POST', '060108_讲师查看自己的班级出勤排行_POST'), }
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————

# permission_list.py

 # CJ.py
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
import re #正则
from crm import models #数据库 # ————————01大类权限————————
#010201_只能查看校区表_GET
def JM_Branch(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'branch'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 010301_只能查看班级表_GET
def JM_ClassList(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'classlist'
if url_model_name == model_name: # 防止其他表通过权限
return True
else:
return False # 010401_只能查看课程表_GET
def JM_Course(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'course'
if url_model_name == model_name: # 防止其他表通过权限
return True
else:
return False # 010501_只能查看客户表_GET
def JM_Customer(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'customer'
if url_model_name == model_name: # 防止其他表通过权限
return True
else:
return False #010601_只能查看跟进表_GET
def JM_CustomerFollowUp(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'customerfollowup'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 010701_只能查看报名表_GET
def JM_Enrollment(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'enrollment'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 010801_只能查看缴费表_GET
def JM_Payment(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'payment'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #010901_只能查看上课表_GET
def JM_CourseRecord(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'courserecord'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 011001_只能查看学习表_GET
def JM_StudyRecord(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'studyrecord'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 011101_只能查看账号表_GET
def JM_UserProfile(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'userprofile'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #011201_只能查看角色表_GET
def JM_Role(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'role'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #010301_只能查看班级表_GET
def JM_Tag(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'tag'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #011401_只能查看一层菜单_GET
def JM_FirstLayerMenu(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'firstlayermenu'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False # 011501_只能查看二层菜单_GET
def JM_SubMenu(request, *args, **kwargs):
url_path = request.path # 获取URL
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[2]
model_name = 'submenu'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #011601_只能查看权限组_GET
def JM_Groups(request,*args,**kwargs):
url_path = request.path # 获取URL
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name=url_list[2]
model_name = 'groups'
if url_model_name == model_name: #防止其他表通过权限
return True
else:
return False #011701_自己密码重置_GET
def own_password_reset(request,*args,**kwargs):
url_path = request.path # 获取URL 路径
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[4] #字符串
url_parameter =int(url_list[3]) #字符串转数字
model_name = 'password_reset' #字符串
if url_model_name == model_name: #防止其他表通过权限
if url_parameter == request.user.id: # 参数 等于 #当前登陆的ID
return True
else:
return False
else:
return False
# ————————01大类权限———————— # ————————02大类权限————————
#020103_销售给自己的客户报名课程_GET
#销售 #客户招生#报名流程一 下一步
def own_enrollment(request,*args,**kwargs):
url_path = request.path #获取URL 路径
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name= url_list[3]
url_parameter =int(url_list[2])
model_name = 'enrollment'
if url_model_name==model_name: #防止其他表通过权限
if request.user.id: #如果有ID
list= request.user.customer_set.all()#获取ID 的客户表
list_id=[]
for obtain in list:#循环客户表ID
results=obtain.id
list_id.append(results)#生成列表
if url_parameter in list_id: #对比URL参数 在不在 客户表ID里
return True
else:
return False
else:
return False #020107_销售给自己的客户审核合同_GET
#销售 # 报名流程三 审核
def own_contract_review(request,*args,**kwargs):
url_path = request.path #获取URL 路径
url_list=re.findall('(\w+)',url_path) #正者表达式 获取参数
url_model_name= url_list[1] #字符串
url_parameter =int(url_list[2]) #字符串转数字
model_name='contract_review' #字符串
if url_model_name==model_name: #防止其他表通过权限
if request.user.id: #如果有ID
list= request.user.enrollment_set.all()#获取ID 的客户表
list_id=[] #数字列表
for obtain in list:#循环客户表ID
results=obtain.id
list_id.append(results)#生成列表
if url_parameter in list_id: #对比URL参数 在不在 列表里
return True
else:
return False
else:
return False # ————————02大类权限———————— # ————————04大类权限————————
# 040103_学生自己的上课记录_GET
def own_studyrecords(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/studyrecords/6/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[1]
url_parameter = int( url_list[2] )
model_name = 'studyrecords'
if url_model_name == model_name: # 防止其他表通过权限
if request.user.id: # 如果有ID
list = request.user.stu_account.enrollment_set.all() # 根据ID关联学生的报名ID
list_id = []
for obtain in list:
results = obtain.id
list_id.append( results ) # 生成列表
if url_parameter in list_id: # 对比URL参数 在不在 ID列表里
return True
else:
return False
else:
return False # 040105_学生自己的作业详情_GET
def own_homework_detail(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/homework_detail/2/25/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[1] #字符串
url_parameter =(int(url_list[2]),) #元组
url_parameter2 = int(url_list[3]), #元组
model_name = 'homework_detail'#字符串
if url_model_name == model_name: #防止其他表通过权限
if request.user.id: # 如果有ID
list_id = request.user.stu_account.enrollment_set.values_list('id') # 根据登陆ID关联学生的报名ID
if url_parameter in list_id: # 对比URL参数 在不在 ID列表里
StudyRecord_id = models.StudyRecord.objects.filter(student_id=url_parameter).values_list('id')
if url_parameter2 in StudyRecord_id: # 对比URL参数2 在不在 ID列表里
return True
else:
return False
else:
return False
else:
return False # ————————04大类权限———————— # ————————05大类权限————————
# 050103_讲师查看自己的课节详情_GET
def own_teacher_class_detail(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/teacher_class_detail/1/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[1]
url_parameter = (int(url_list[2]),) # <class 'tuple'> (1,)
model_name = 'teacher_class_detail'
if url_model_name == model_name: #防止其他表通过权限
if request.user.id: # 如果有ID
list_id = request.user.classlist_set.values_list('id') # 根据ID获取班级ID
if url_parameter in list_id: # 对比URL参数 在不在 ID列表里
return True
else:
return False
else:
return False # 050105_讲师查看自己的课节学员_GET
def own_teacher_lesson_detail(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/teacher_lesson_detail/2/2/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[1] #字符串
url_parameter = int(url_list[2]), #元组
url_parameter2 = (int(url_list[3]),) #元组
model_name = 'teacher_lesson_detail'#字符串
if url_model_name == model_name: #防止其他表通过权限
if request.user.id: # 如果有ID
list_id= request.user.classlist_set.values_list( 'id' ) # 元组列表 #根据登陆ID 反查班级ID列表
if url_parameter in list_id : # 对比URL参数 在不在 ID列表里
CourseRecord_id = models.CourseRecord.objects.filter( from_class_id=url_parameter ).values_list( 'id' )# 元组列表
if url_parameter2 in CourseRecord_id: # 对比URL参数2 在不在 ID列表里
return True
else:
return False
else:
return False
else:
return False # 050107_讲师自己的学员作业下载_GET
def own_howk_down(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/homeworks/3/3/17/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = url_list[1] #字符串
url_parameter = (int(url_list[2]),) #元组# <class 'tuple'> (1,)
url_parameter2 = (int(url_list[3]),) #元组
model_name = 'homeworks' #字符串
if url_model_name == model_name: #防止其他表通过权限
if request.user.id: # 如果有ID
list_id = request.user.classlist_set.values_list( 'id' ) # 元组列表 #根据登陆ID 反查班级ID列表
if url_parameter in list_id : # 对比URL参数 在不在 ID列表里
CourseRecord_id = models.CourseRecord.objects.filter( from_class_id=url_parameter ).values_list( 'id' )
if url_parameter2 in CourseRecord_id: # 对比URL参数2 在不在 ID列表里
return True
else:
return False
else:
return False
else:
return False # ————————05大类权限———————— # ————————06大类权限———————— # 060101_讲师查看自己的班级排名详情_GET
def JM_crm_classlist_teachers(request, *args, **kwargs):
url_path = request.path # 获取URL 路径 /bpm/coursetop_details/3/
url_list = re.findall( '(\w+)', url_path ) # 正者表达式 获取参数
url_model_name = (url_list[1],)#字符串元组
url_parameter = (int(url_list[2]),) # 元组 #<class 'tuple'> (1,)
model_name =[('coursetop_details',),('coursetop_score',),('coursetop_homework',),('coursetop_attendance',),]
if url_model_name in model_name: #防止其他表通过权限
if request.user.id: # 如果有ID
list_id = request.user.classlist_set.values_list('id') # 根据ID获取班级ID
print('list_id::',list_id)
if url_parameter in list_id: # 对比URL参数 在不在 ID列表里
return True
else:
return False
else:
return False # ————————06大类权限———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————

# CJ.py

 # permission.py
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————
from django.urls import resolve # resolve解析URL
from django.shortcuts import render,redirect,HttpResponse #页面返回
from permissions.permission_list import perm_dic #权限字典 def perm_check(*args,**kwargs):
print( '执行perm_check:', *args, **kwargs )
request = args[0]#
# print(request) #<WSGIRequest: GET '/king_admin/crm/firstlayermenu/4/change/'> resolve_url_obj = resolve(request.path)#反解URL路径#获取当前的URL# resolve解析URL#生成实例
print('反解URL路径:',resolve_url_obj)#ResolverMatch(func=permissions.permission.inner, args=('crm', 'firstlayermenu', '4'), kwargs={}, url_name=table_change, app_names=[], namespaces=[])
current_url_name = resolve_url_obj.url_name # 当前url的url_name
print('当前用户:',request.user,'当前url的url_name:',current_url_name)#admin2 当前url的url_name: table_change permission_list= request.user.user_permissions.values_list('codename') # 根据 登陆的ID 获取 拥有的权限列表
print('拥有的权限列表',permission_list) permission_group = request.user.groups.all().values_list('permissions__codename') # 根据 登陆的ID 获取 拥有的组
print('拥有的权限组',permission_group) match_key = None
match_results = [False,] #后面会覆盖,加个False是为了让all(match_results)不出错 for permission_key,permission_val in perm_dic.items():#从权限字典中取相关字段 #crm_table_index':['1','table_index','GET',[],{},],
# print('循环权限表',((permission_key),))
if ((permission_key),) in permission_list or ((permission_key),) in permission_group:#权限列表是元组
per_url_name = permission_val[0] #URL
per_method = permission_val[1] #GET #POST #请求方法
perm_args = permission_val[2] # 列表参数
perm_kwargs = permission_val[3]# 字典参数
custom_perm_func = None if len(permission_val) == 4 else permission_val[4] #url判断 #自定义权限钩子
# 'crm_can_access_my_clients':['table_list','GET',[],{'perm_check':33,'arg2':'test'}, custom_perm_logic.only_view_own_customers],
# print('URL:',per_url_name,'请求方法:',per_method,'列表参数:',perm_args,'字典参数:',perm_kwargs,'自定义权限钩子:',custom_perm_func) if per_url_name == current_url_name: #权限字典的 URL ==当前请求的url #crm_table_index':['URL','请求方法',[列表参数],{字典参数},],
if per_method == request.method: #权限字典的 请求方法 == 当前请求的方法 #crm_table_index':['URL','请求方法',[列表参数],{字典参数},],
#逐个匹配参数,看每个参数时候都能对应的上。
args_matched = False #参数匹配 #仅供参数
for item in perm_args: #循环列表参数 #crm_table_index':['URL','请求方法',[列表参数],{字典参数},],
request_method_func = getattr(request,per_method) #反射 #请求方法 #GET #POST
if request_method_func.get(item,None):# 如果request字典中有此参数
args_matched = True
else:
print("参数不匹配......")
args_matched = False
break # 有一个参数不能匹配成功,则判定为假,退出该循环。
else:
args_matched = True #没有执行 break 表示 列表匹配成功 #防止列表没有使用参数时出错 #匹配有特定值的参数
kwargs_matched = False
for k,v in perm_kwargs.items(): #循环字典参数#crm_table_index':['URL','请求方法',[列表参数],{字典参数},],
request_method_func = getattr(request, per_method) #反射 #请求方法 #GET #POST
arg_val = request_method_func.get(k, None) # request字典中有此参数
print("perm kwargs check:",arg_val,type(arg_val),v,type(v))
if arg_val == str(v): #匹配上了特定的参数 及对应的 参数值, 比如,需要request 对象里必须有一个叫 user_id=3的参数
kwargs_matched = True
else:
kwargs_matched = False
break # 有一个参数不能匹配成功,则判定为假,退出该循环。
else:
kwargs_matched = True #自定义权限钩子
perm_func_matched = False
if custom_perm_func: #如果有定义
if custom_perm_func(request,args,kwargs):#def only_view_own_customers(request,*args,**kwargs):
perm_func_matched = True
else:
perm_func_matched = False #使整条权限失效
print('自定义权限钩子没有通过',perm_func_matched)
else: #没有定义权限钩子,所以默认通过
perm_func_matched = True match_results = [args_matched,kwargs_matched,perm_func_matched] #列表
print("匹配结果: ", match_results) # [True, True, True]
if all(match_results): #都匹配上了 #都返回 True
match_key = permission_key # 给 match_key = None 赋值
break #跳出大循环 if all(match_results): #如果都匹配成功 #'crm_table_index':['table_index','GET',[],{},],
app_name, *per_name = match_key.split('_') #先给app_name赋一个值,其他的值都给*per_name 'crm_table_index':
print("权限名:",match_key,'权限:',match_results)#crm_010902_only_view_CourseRecord_POST [True, True, True]
print('分割:',app_name, *per_name) # crm 010902 only view CourseRecord POST
perm_obj = '%s.%s' % (app_name,match_key)#'crm.table_index' # url(r'^(\w+)/$', views.table_index, name='table_index'), # 单个具体app页面
print("生成权限:",perm_obj) #crm.crm_010902_only_view_CourseRecord_POST
if request.user.has_perm(perm_obj):
print('当前用户有此权限')
return True
else:
print('当前用户没有该权限')
return False
else:
print("未匹配到权限项,当前用户无权限") def check_permission(func):
print('权限func',func)#权限func <function table_data_list at 0x030636A8> #循环 URL name
def inner(*args,**kwargs):
print('开始权限匹配:',type(args))
request = args[0]#请求第一个
print('判断登陆情况:')
if request.user.id == None:
print('未登陆')
return redirect( '/gbacc/gbacc_login/' )#返回登陆页面
else:
if request.user.is_superuser == True:
print('超级管理员')
return func( *args, **kwargs ) #直接返回 真
print( '已登陆,判断有perm_check(*args,**kwargs)去执行' )
if not perm_check(*args,**kwargs): #如果返回不为真 #没权限
print('#没权限',perm_check(*args,**kwargs))
request = args[0]
return HttpResponse('你没有这个权限')
print('有权限',func(*args,**kwargs)) #<HttpResponse status_code=200, "text/html; charset=utf-8">
return func(*args,**kwargs)
print('inner',inner)
return inner #返回 真或假
# ————————74PerfectCRM实现CRM权限和权限组限制URL————————

# permission.py

 # views

 # ————————02PerfectCRM创建ADMIN页面————————
from django.shortcuts import render # ————————04PerfectCRM实现King_admin注册功能————————
# from django import conf #配置文件
# print("dj conf:",conf) #配置文件
# print("dj conf:",conf.settings)#配置文件.设置
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————04PerfectCRM实现King_admin注册功能————————
from king_admin import app_config # 自动调用 动态加载类和函数
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————04PerfectCRM实现King_admin注册功能————————
# from king_admin.base_admin import registered_sites # registered_sites={}
from king_admin import base_admin
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————11PerfectCRM实现King_admin基本分页————————
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # 分页功能
# ————————11PerfectCRM实现King_admin基本分页———————— # ————————46PerfectCRM实现登陆后页面才能访问————————
from django.contrib.auth.decorators import login_required
# ————————46PerfectCRM实现登陆后页面才能访问———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL———————— def app_index(request):
# ————————04PerfectCRM实现King_admin注册功能————————
# for app in conf.settings.INSTALLED_APPS:
# print(app)#循环打印 配置文件.设置.安装应用程序#.Perfectcustomer\settings里的INSTALLED_APPS列表
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————04PerfectCRM实现King_admin注册功能————————
# return render(request, 'king_admin/app_index.html')
# print("registered_sites",registered_sites)
# return render(request, 'king_admin/app_index.html')
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————04PerfectCRM实现King_admin注册功能————————
# print("registered_sites", base_admin.registered_sites)
# return render(request, 'king_admin/app_index.html')
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————05PerfectCRM实现King_admin注册功能获取内存————————
print("registered_sites", base_admin.site.registered_sites)
return render(request, 'king_admin/app_index.html', {"site": base_admin.site}) # ————————05PerfectCRM实现King_admin注册功能获取内存———————— # ————————02PerfectCRM创建ADMIN页面———————— # ————————13PerfectCRM实现King_admin分页页数————————
# 处理def table_data_list(request,app_name,model_name):里的内容,
def filter_querysets(request, queryset):
condtions = {} # 定义一个字典用来存过滤的条件
for k, v in request.GET.items(): # 不需要空的,判断是否为空
# ————————18PerfectCRM实现King_admin搜索关键字————————
# ————————17PerfectCRM实现King_admin单列排序————————
# if k=="page":continue##kingadmin分页功能 # if k=="page":continue##kingadmin分页功能 #写法一
# elif k=="_o":continue##kingadmin排序功能 <a href="?_o={{ column }}">{{ column }}</a> # if k in ("page","_o") :continue #kingadmin分页功能 #kingadmin排序功能 #写法二 # if k == "page"or k == "_o": #保留的分页关键字 和 排序关键字 #写法三
# continue #continue是结束单次循环
# ————————17PerfectCRM实现King_admin单列排序————————
if k in ("page", "_o", "_q"): continue # kingadmin分页,排序,搜索#判断标签是否存在 自定义的名称
# ————————18PerfectCRM实现King_admin搜索关键字———————— # ————————15PerfectCRM实现King_admin多条件过滤————————
if v:
condtions[k] = v # 进行配对字典
# ————————15PerfectCRM实现King_admin多条件过滤————————
query_res = queryset.filter(**condtions) return query_res, condtions # ————————13PerfectCRM实现King_admin分页页数———————— # ————————59PerfectCRM实现king_admin行内编辑————————
from king_admin import form def batch_update(request, editable_data, admin_obj):
"""table objects batch update , for list_editable feature"""
errors = [] # 错误信息
for row_data in editable_data:
obj_id = row_data.get('id') # 获取这行ID号
try:
if obj_id:
print("如果有ID编辑数据:", row_data, list(row_data.keys()))
obj = admin_obj.model.objects.get(id=obj_id) # 获取编辑的ID
model_form = form.create_form(admin_obj.model, list(row_data.keys()),
admin_obj, request=request, partial_update=True) # 进行数据验证处理
form_obj = model_form(instance=obj, data=row_data) # 编辑的ID #验证的内容
if form_obj.is_valid(): # 验证通过
form_obj.save() # 保存新内容
print('保存。。。。') else:
print("可编辑列表形式", row_data, form_obj.errors) errors.append([form_obj.errors, obj]) # 添加错误信息 # for column in row_data:
# if column != "id":#id no need change
# #print("-----column",column,row_data[column],type(row_data[column]))
# if row_data[column] in ('True','False'):
# if obj._meta.get_field(column).get_internal_type() == "BooleanField":
# setattr(obj, column, eval(row_data[column]))
# #print("setting column [%s] to [%s]" %(column,row_data[column]), eval(row_data[column]))
# else:
# setattr(obj, column, row_data[column])
# else:
# setattr(obj,column,row_data[column])
#
# obj.save() # except Exception as e:
except KeyboardInterrupt as e:
return False, [e, obj]
if errors:
return False, errors
return True, [] # ————————59PerfectCRM实现king_admin行内编辑———————— # ————————08PerfectCRM实现King_admin显示注册表的字段表头————————
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def table_data_list(request, app_name, model_name):
# 通过2个参数到base_admin里获取class AdminRegisterException(Exception): 的对象
admin_obj = base_admin.site.registered_sites[app_name][model_name] # base_admin # ————————24PerfectCRM实现King_admin自定义操作数据————————
if request.method == "POST": # 批量操作
action = request.POST.get("action_select") # 要调用的自定制功能函数
selected_ids = request.POST.get("selected_ids") # 前端提交的数据
print(selected_ids, type(selected_ids), "selected_ids-----")
# if type(selected_ids)!='str':
# selected_ids = json.loads(selected_ids)#进行转换数据
print(selected_ids, type(action), action, "selected_ids==========")
# print("action:",selected_ids,action)
# ————————59PerfectCRM实现king_admin行内编辑————————
import json
editable_data = request.POST.get("editable_data") # 获取前端可编辑的数据
print('编辑数据:', editable_data)
if editable_data: # for list editable
editable_data = json.loads(editable_data) # 进行转换数据
# print("editable",editable_data)
res_state, errors = batch_update(request, editable_data, admin_obj) # 进行部分更新操作
else:
# ————————59PerfectCRM实现king_admin行内编辑————————
if selected_ids:
# selected_ids = json.loads(selected_ids)#进行转换数据
selected_objs = admin_obj.model.objects.filter(id__in=selected_ids.split(',')) # 返回之前所选中的条件
else:
raise KeyError('错误,没有选择对象!') if hasattr(admin_obj, action):
action_func = getattr(admin_obj, action) # 如果admin_obj 对象中有属性action 则打印self.action的值,否则打印'not find'
request._admin_action = action # 添加action内容
print(request._admin_action, action, '<--------')
return action_func(request, selected_objs)
# ————————24PerfectCRM实现King_admin自定义操作数据———————— # ————————09PerfectCRM实现King_admin显示注册表的内容————————
admin_obj.querysets = admin_obj.model.objects.all() # 取数据 传到 前端
# ————————09PerfectCRM实现King_admin显示注册表的内容———————— # ————————11PerfectCRM实现King_admin分页显示条数————————
# from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # 分页功能#放在顶上导入
obj_list = admin_obj.model.objects.all() # 取数据 传到 前端 #base_admin #获取传过来的所有对象 # ————————13PerfectCRM实现King_admin分页页数————————
queryset, condtions = filter_querysets(request, obj_list) # base_admin # 调用条件过滤
# ————————13PerfectCRM实现King_admin分页页数———————— # ————————18PerfectCRM实现King_admin搜索关键字————————
queryset = get_queryset_search_result(request, queryset, admin_obj) ##搜索后
# ————————18PerfectCRM实现King_admin搜索关键字———————— # ————————26PerfectCRM实现King_admin自定义排序————————
sorted_queryset = get_orderby(request, queryset, admin_obj) # 排序后的结果
# ————————17PerfectCRM实现King_admin单列排序————————
# sorted_queryset = get_orderby(request, queryset) #排序后的结果
# ————————15PerfectCRM实现King_admin多条件过滤————————
# paginator = Paginator(obj_list,admin_obj.list_per_page) #kingadmin里class CustomerAdmin(BaseAdmin):
# paginator = Paginator(queryset, admin_obj.list_per_page)
# ————————15PerfectCRM实现King_admin多条件过滤————————
paginator = Paginator(sorted_queryset, admin_obj.list_per_page)
# ————————17PerfectCRM实现King_admin单列排序————————
# ————————26PerfectCRM实现King_admin自定义排序———————— page = request.GET.get('page')
try:
objs = paginator.page(page) # 当前的页面的数据
except PageNotAnInteger:
# 如果页面不是一个整数,交付第一页。
objs = paginator.page(1)
except EmptyPage:
# 如果页面的范围(例如9999),交付最后一页的搜索结果。
objs = paginator.page(paginator.num_pages)
admin_obj.querysets = objs # base_admin # ————————13PerfectCRM实现King_admin分页页数————————
admin_obj.filter_condtions = condtions # base_admin
# ————————13PerfectCRM实现King_admin分页页数———————— # ————————11PerfectCRM实现King_admin分页显示条数———————— return render(request, "king_admin/table_data_list.html", locals()) # ————————08PerfectCRM实现King_admin显示注册表的字段表头———————— # ————————17PerfectCRM实现King_admin单列排序————————
# def get_orderby(request,queryset):
# order_by_key = request.GET.get("_o") #获取URL里有没有("_o") <a href="?_o={{ column }}">{{ column }}</a>
# #页面刚开始没有这个值
# if order_by_key != None: #有("_o")这个值 就进行排序
# query_res = queryset.order_by(order_by_key)
# else: #没有就不排序,直接返回
# query_res = queryset
# return query_res #排序时会错 # orderby_key = request.GET.get("_o")
# if orderby_key:
# return queryset.order_by(orderby_key)
# return queryset # 在table_data_list添加
# def table_data_list(request,app_name,model_name): #详细列表
# sorted_queryset = get_orderby(request, queryset)
# 在filter_querysets添加
# if k == "page"or k == "_o": #保留的分页关键字 和 排序关键字
# ————————17PerfectCRM实现King_admin单列排序———————— # ————————26PerfectCRM实现King_admin自定义排序————————
def get_orderby(request, queryset, admin_obj):
orderby_key = request.GET.get("_o")
# order_by_key1=order_by_key.strip()
if orderby_key: # 有获取到字段
query_res = queryset.order_by(orderby_key.strip()) # .strip()默认删除空白符(包括'\n', '\r', '\t', ' ')
else:
if admin_obj.ordering: # 查看kingadmin‘有没有 ordering = '-qq' # 自定义排序
query_res = queryset.order_by("%s" % admin_obj.ordering)
else:
query_res = queryset.order_by('-id') # 默认倒序
return query_res # 在table_data_list添加
# def table_data_list(request,app_name,model_name): #详细列表
# sorted_queryset = get_orderby(request, queryset, admin_obj) # 排序后的结果
# ————————26PerfectCRM实现King_admin自定义排序———————— # ————————18PerfectCRM实现King_admin搜索关键字————————
from django.db.models import Q def get_queryset_search_result(request, queryset, admin_obj):
search_key = request.GET.get("_q", "") # 取定义名,默认为空
q_obj = Q() # 多条件搜索 #from django.db.models import Q
q_obj.connector = "OR" # or/或 条件
for column in admin_obj.search_fields: # 搜索目标crm/kingadmin里class CustomerAdmin(BaseAdmin):search_fields = ('name','qq',)
q_obj.children.append(("%s__contains" % column, search_key)) # 运态添加多个条件
res = queryset.filter(q_obj) # 对数据库进行条件搜索
return res # 返回结果 # 在table_data_list添加
# def table_data_list(request,app_name,model_name): #详细列表
# queryset = get_queryset_search_result(request,queryset,admin_obj)
# ————————18PerfectCRM实现King_admin搜索关键字———————— # ————————19PerfectCRM实现King_admin数据修改————————
from king_admin import forms # 修改内容
# def table_change(request,app_name,model_name):
# obj_form = forms.CustomerModelForm() #创建一个空表单
# return render(request,"kingadmin/table_change.html",locals())
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def table_change(request, app_name, model_name, obj_id):
admin_obj = base_admin.site.registered_sites[app_name][model_name] # 获取表对象
# kingadmin/forms.py里def CreateModelForm(request,admin_obj):
model_form = forms.CreateModelForm(request, admin_obj=admin_obj) ##modelform 生成表单 加验证
# obj_form = model_form() # 表单
obj = admin_obj.model.objects.get(id=obj_id) # 根据ID获取数据记录 # ————————28PerfectCRM实现King_admin编辑限制————————
# ————————20PerfectCRM实现King_admin数据修改美化————————
# #面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
# obj_form = model_form(instance=obj) # 数据传入表单 if request.method == "GET": # 如果是 GET 表示 是添加记录
obj_form = model_form(instance=obj) # 数据传入表单
elif request.method == "POST": # 如果是 POST 表示 是修改后的数据
obj_form = model_form(instance=obj, data=request.POST) # 更新数据
if obj_form.is_valid():
obj_form.save()
# ————————20PerfectCRM实现King_admin数据修改美化————————
# ————————28PerfectCRM实现King_admin编辑限制———————— return render(request, "king_admin/table_change.html", locals()) # ————————19PerfectCRM实现King_admin数据修改———————— # ————————21PerfectCRM实现King_admin查看页面美化————————
# 单个具体app页面
@login_required # 登陆后页面才能访问
def table_index(request, app_name):
bases = base_admin.site.registered_sites[app_name] # 取出对应app对象
return render(request, 'king_admin/table_index.html', {"site": bases, 'app_name': app_name}) # ————————21PerfectCRM实现King_admin查看页面美化———————— # ————————22PerfectCRM实现King_admin数据添加————————
from django.shortcuts import redirect # kingadmin添加内容 @login_required # 登陆后页面才能访问
@check_permission #权限控制
def table_add(request, app_name, model_name):
admin_obj = base_admin.site.registered_sites[app_name][model_name] # 获取表对象
# ————————32PerfectCRM实现King_admin添加不进行限制————————
admin_obj.is_add_form = True # 表示为新增表单
# ————————32PerfectCRM实现King_admin添加不进行限制————————
model_form = forms.CreateModelForm(request, admin_obj=admin_obj) ##modelform 生成表单 加验证
if request.method == "GET":
obj_form = model_form() # 跳转过来的为空
elif request.method == "POST":
obj_form = model_form(data=request.POST) # 创建数据 # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
password = request.POST.get('password') # 取前端输入的密码
email = request.POST.get('email') # 取前端输入的邮箱
# ————————37PerfectCRM实现King_admin添加用户时密码加密———————— if obj_form.is_valid():
# ————————32PerfectCRM实现King_admin添加不进行限制————————
# obj_form.save()
try:
obj_form.save() # 表单验证通过保存
except Exception as e:
return redirect("/king_admin/%s/%s/" % (app_name, model_name)) # 转到之前的页面
# ————————32PerfectCRM实现King_admin添加不进行限制————————
if not obj_form.errors: # 没有错误返回原来的页面 # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
if email:
obj = admin_obj.model.objects.filter(email=email).first() # 对象
obj.set_password(password) # 加密
try:
obj.save() # 表单验证通过保存
except Exception as e:
return redirect("/king_admin/%s/%s/" % (app_name, model_name))
# ————————37PerfectCRM实现King_admin添加用户时密码加密———————— # from django.shortcuts import redirect
return redirect("/king_admin/%s/%s/" % (app_name, model_name))
return render(request, "king_admin/table_add.html", locals()) # ————————22PerfectCRM实现King_admin数据添加———————— # ————————23PerfectCRM实现King_admin数据删除————————
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def table_delete(request, app_name, model_name, obj_id):
admin_obj = base_admin.site.registered_sites[app_name][model_name] # 表类
objs=admin_obj.model.objects.filter(id=obj_id)#类的对象 # ————————33PerfectCRM实现King_admin编辑整张表限制————————
# if request.method=='POST':
# objs.delete()#删除
# return redirect("/king_admin/%s/%s/" % (app_name,model_name))#转到列表页面 app_name=app_name
if admin_obj.readonly_table:
errors={'锁定的表单':'该表单:<%s>,已经锁定,不能删除当前记录!'%model_name}
else:
errors={}
if request.method=='POST':
if not admin_obj.readonly_table:
objs.delete()#删除
return redirect("/king_admin/%s/%s/" % (app_name,model_name))#转到列表页面
# ————————33PerfectCRM实现King_admin编辑整张表限制———————— return render(request, "king_admin/table_delete.html", locals()) # locals 返回一个包含当前范围的局部变量字典。 # ————————23PerfectCRM实现King_admin数据删除———————— # ————————36PerfectCRM实现King_admin密码修改————————
# 密码修改
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def password_reset(request, app_name, model_name, obj_id):
admin_obj = base_admin.site.registered_sites[app_name][model_name] # 表类
model_form = forms.CreateModelForm(request, admin_obj=admin_obj) # modelform 生成表单 加验证
obj = admin_obj.model.objects.get(id=obj_id) # 类表的对象
errors = {} # 错误提示
if request.method == 'POST':
_password1 = request.POST.get('password1') # 获取页面输入的值
_password2 = request.POST.get('password2') # 获取页面输入的值
if _password1 == _password2:
if len(_password1) > 5:
obj.set_password(_password1) # 继承Django方法 #加密
obj.save() # 保存
return redirect(request.path.rstrip('password/') + ('/change/')) # 替换URL名
else:
errors['password_too_short'] = '必须不少于6字符'
else:
errors['invalid_password'] = '两次输入的密码不一样' # 密码不一致 return render(request, "king_admin/password_reset.html", locals()) # locals 返回一个包含当前范围的局部变量字典。 # ————————36PerfectCRM实现King_admin密码修改———————— # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
def password_add(request, app_name, model_name):
return redirect("/king_admin/%s/%s/add/" % (app_name, model_name)) # 转到添加页面
# ————————37PerfectCRM实现King_admin添加用户时密码加密————————

# views

 # sales_views.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from django.db import IntegrityError # 主动捕捉错误信息
from django.shortcuts import render # 页面返回
from crm import models # 数据库
from bpm.bpm_auxiliary import bpm_forms # 自定制 forms
from django.contrib.auth.decorators import login_required # 登陆后页面才能访问 # ————————47PerfectCRM实现CRM客户报名流程————————
from django.core.mail import send_mail
# send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们)
import random
import datetime # 获取时间#登陆过期
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
# 发送邮件的功能 #验证码#密码
class stmp():
def __init__(self):
self.emaillist = [] # 发送给谁
self.code = None # 验证码#密码 def stmps(self, request, email, msg_mail): # 传参数#页面,session #邮箱,发送给谁 #内容
self.emaillist.append(email) # 将邮箱地址添加到调用Django发送邮件功能
# ——————生成验证码——————
_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
chars = ''.join((_letter_cases, _upper_cases, _numbers)) # 变成一条字符串
list = random.sample(chars, 4) # 从一条字符串随机选4个字符变成列表
self.code = ''.join(list) # 列表变字符串
# ——————生成验证码——————
# ——————调用Django发送邮件——————
title = 'PerfectCRM项目自动邮件:%s' % self.code # 邮件标题#防止一样的内容被邮箱屏蔽
send_mail(title, # 邮件标题
msg_mail, # 验证码内容
'perfectcrm@sina.cn', # 发送的邮箱 #根据情况重新配置
self.emaillist, # 接受的邮箱
fail_silently=False, # 静默,抛出异常
)
print('发送邮件成功!没收到要换标题!检查发送邮箱的配置!')
# ——————调用Django发送邮件——————
# ————————47PerfectCRM实现CRM客户报名流程————————
# ————————47PerfectCRM实现CRM客户报名流程————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
import random # 随机
import string # 字母 数字
from django.core.cache import cache # 缓存
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— # 报名填写 销售
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def enrollment(request, customer_id):
msgs = {} # 错误信息
customer_obj = models.Customer.objects.get(id=customer_id) # 取到客户信息记录 #返回到页面#报名人
consultant_obj = models.UserProfile.objects.get(id=request.user.id) # 报名课程顾问 stmp_mail = {} # 邮件发送成功
stmpemail = stmp() # 实例化发送邮件的功能
email = request.POST.get('email') # 让页面POST提交的值,在页面GET后仍然存在显示
if request.method == "POST":
enroll_form = bpm_forms.EnrollmentForm(request.POST) # 获取数据
if enroll_form.is_valid(): # 表单验证 # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/"
msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/{random_str}/ "
random_str = ''.join(random.sample(string.ascii_lowercase + string.digits, 8)) # 生成8位随机字符串 #URL使用
url_str = '''customer/registration/{enroll_obj_id}/{random_str}/''' # 报名链接
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— try:
enroll_form.cleaned_data['customer'] = customer_obj # 添加学员对象 记录 #报名人
enroll_form.cleaned_data['consultant'] = consultant_obj # 报名课程顾问
enroll_obj = models.Enrollment.objects.create(**enroll_form.cleaned_data) # 创建记录 # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id,随机字符串,报名链接
sort_url = enroll_obj.id # 获取报名表对应的ID
cache.set(enroll_obj.id, random_str, 61000) # 加入过期时间 #URL使用 # cache缓存
msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名记录对应的id,随机字符串,报名链接
url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名链接
print(url_str)
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
except IntegrityError as e:
# 取到这条记录
enroll_obj = models.Enrollment.objects.get(customer_id=customer_obj.id,
enrolled_class_id=enroll_form.cleaned_data[
'enrolled_class'].id) # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
if enroll_obj.contract_agreed:#学员已经同意合同,提交了身份证
#return redirect('/crm/contract_review/%s/'%enroll_obj.id)#跳转到审核页面
return render(request,'bpm_sales/contract_prompt.html',locals())#跳转提示页面
# ————————52PerfectCRM实现CRM客户报名流程学生合同审核———————— enroll_form.add_error('__all__', '记录已经存在,不能重复创建!') # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id
cache.set(enroll_obj.id, random_str, 61000) # 加入过期时间 #URL使用 # cache缓存
msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名记录对应的id
url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名链接
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— if email:
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s" %enroll_obj.id
msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s/%s" %(enroll_obj.id,random_str)
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
stmpemail.stmps(request, email, msg_mail) # 发送邮件
stmp_mail['ok'] = "邮件已发送成功!" else:
enroll_form = bpm_forms.EnrollmentForm() # modelform表单
return render(request, 'bpm_sales/enrollment.html', locals())
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#学员合同签定 # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
import os
from PerfectCRM import settings
import json
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
from django.shortcuts import HttpResponse #页面返回
# def stu_registration(request,enroll_id):
def stu_registration(request,enroll_id,random_str):
# enroll_obj=models.Enrollment.objects.get(id=enroll_id)#获取报名记录
if cache.get(enroll_id) == random_str: # 判断链接失效了没有
enroll_obj = models.Enrollment.objects.get(id=enroll_id) # 报名记录
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
enrolled_path='%s/%s/'%(settings.ENROLLED_DATA,enroll_id)#证件上传路径
img_file_len=0 #文件
if os.path.exists(enrolled_path):#判断目录是否存在
img_file_list=os.listdir(enrolled_path)#取目录 下的文件
img_file_len=len(img_file_list)
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
if request.method == "POST": # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
ret=False
data=request.POST.get('data')
if data:#如果有删除动作
del_img_path="%s/%s/%s"%(settings.ENROLLED_DATA,enroll_id,data)#路径
print(del_img_path,'=-=-=-=-=-=')
os.remove(del_img_path)
ret=True
return HttpResponse(json.dumps(ret))
if request.is_ajax():#ajax上传图片 #异步提交
print('ajax上传图片 #异步提交中。。。 ',request.FILES)
enroll_data_dir="%s/%s"%(settings.ENROLLED_DATA,enroll_id)#路径 #重要信息不能放在静态文件中
if not os.path.exists(enroll_data_dir):#如果不存目录
os.makedirs(enroll_data_dir,exist_ok=True)#创建目录
for k,file_obj in request.FILES.items(): #循环字典 #上传的文件
with open("%s/%s"%(enroll_data_dir,file_obj.name),'wb') as f: #打开一个文件#路径#获取文件名
for chunk in file_obj.chunks():#循环写入文件 # chunks块
f.write(chunk) #保存文件
return HttpResponse('上传完成!')
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— customer_form = bpm_forms.CustomerForm(request.POST, instance=enroll_obj.customer) # 生成表单验证
if customer_form.is_valid(): # 表单验证通过
customer_form.save() # 保存
enroll_obj.contract_agreed = True # 同意协议
enroll_obj.save() # 保存
status = 1 # 修改报名状态 # 1 已经报名
return render(request, 'bpm_sales/stu_registration.html', locals()) else:
if enroll_obj.contract_agreed == True: # 如果协议已经签订
status = 1 # 修改报名状态 # 1 已经报名
else:
status = 0
customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer) # 生成表单
# customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer) # 生成表单
# ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证———————— return render(request,'bpm_sales/stu_registration.html',locals())
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
else:
return HttpResponse('链接失效,非法链接,请自重!')
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
from django.shortcuts import redirect
#查询流程提示页面
def contract_prompt(request,enroll_id):
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象
enroll_form= bpm_forms.EnrollmentForm(instance=enroll_obj)#报名表对象
customers_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#学员的信息
return render(request,'bpm_sales/contract_prompt.html',locals()) # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
from bpm.bpm_auxiliary.pagination import Page #分页
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
# #待审核
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def not_audit(request):
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
# sign=models.Enrollment.objects.all()#所有的报名表
# print(sign,'sign----->')
sign=models.Enrollment.objects.filter(contract_agreed=True,contract_approved=False).all()#所有的报名表 page = Page(request.GET.get('p', 1), len(sign)) #当前页数 默认为1 #总数量
sign = sign[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/not_audit/') #总页数 传入url
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
return render(request, 'bpm_sales/not_audit.html', locals())# #审核合同
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def contract_review(request,enroll_id):
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象
contract_review = request.user.name #当前登陆人 #合同审核人
#payment_form=forms.PaymentForm()#生成表单
enroll_form= bpm_forms.EnrollmentForm(instance=enroll_obj)#报名表对象
customer_form= bpm_forms.CustomerForm(instance=enroll_obj.customer)#学员的信息
enrolled_path='%s/%s/'%(settings.ENROLLED_DATA,enroll_id)#证件上传路径
if os.path.exists(enrolled_path):#判断目录是否存在
file_list=os.listdir(enrolled_path)#取目录 下的文件
imgs_one=file_list[0] #图片1
imgs_two=file_list[1] #图片2
if request.method=="POST":
enroll_obj.contract_approved = True # 审核通过
enroll_obj.save() #保存
enroll = models.Enrollment.objects.filter(id=enroll_id).update(contract_review=contract_review)#合同审核人
print('审核通过。。。')
return redirect('/bpm/not_audit/')#跳转到待审核
return render(request, 'bpm_sales/contract_review.html', locals())#
#驳回合同
def enrollment_rejection(request,enroll_id):
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#报名表的对象
enroll_obj.contract_agreed=False#修改学员已经同意核同
enroll_obj.save() #保存
return redirect('/bpm/customer/%s/enrollment/'%enroll_obj.customer.id)#跳转到enrollment_rejection
# ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————

# sales_views.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 # 登陆后页面才能访问 # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL———————— # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
from bpm.bpm_auxiliary.pagination import Page #分页
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— # #待缴费
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def not_payment(request): # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
# sign=models.Enrollment.objects.all()#所有的报名表
sign=models.Enrollment.objects.filter(contract_approved=True,Pay_cost=False).all()#所有的报名表 page = Page(request.GET.get('p', 1), len(sign)) #当前页数 默认为1 #总数量
sign = sign[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/not_payment/') #总页数 传入url
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— return render(request, 'bpm_financial/not_payment.html', locals())#
# 已缴费
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def already_payment(request): # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
# sign=models.Enrollment.objects.all()#所有的报名表
sign=models.Enrollment.objects.filter(contract_approved=True,Pay_cost=True).all()#所有的报名表 page = Page(request.GET.get('p', 1), len(sign)) #当前页数 默认为1 #总数量
sign = sign[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/already_payment/') #总页数 传入url
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— return render(request, 'bpm_financial/already_payment.html', locals())#
#缴费视图
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def payment(request,enroll_id):
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
# sign=models.Payment.objects.all()#所有的报名表#前端对比用户#缴费记录
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
enroll_obj=models.Enrollment.objects.get(id=enroll_id)#取对象
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
sign=models.Payment.objects.filter(customer=enroll_obj.customer).all()#所有的报名表#前端对比用户#缴费记录
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
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()#生成表单 # ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页————————
page = Page( request.GET.get( 'p', 1 ), len( sign ) ) # 当前页数 默认为1 #总数量
sign = sign[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str( '/bpm/payment/%s/'%enroll_id ) # 总页数 传入url
# ————————68PerfectCRM实现CRM业务流程(bpm)报名缴费分页———————— return render(request, 'bpm_financial/payment.html', locals())
# ————————53PerfectCRM实现CRM客户报名流程缴费————————

# financial_views.py

 # student_views.py
# ————————60PerfectCRM实现CRM学生上课记录————————
from django.shortcuts import render #页面返回
from crm import models #数据库
from django.contrib.auth.decorators import login_required # 登陆后页面才能访问 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
from bpm.bpm_auxiliary.pagination import Page #分页
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL———————— #学生报名的课程
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def student_course(request):
if request.user.stu_account:
enrollmentlist=request.user.stu_account.enrollment_set.all()#根据账号表关联的ID获取06学员报名信息表 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
page = Page(request.GET.get('p', 1), len(enrollmentlist)) #当前页数 默认为1 #总数量
enrollmentlist = enrollmentlist[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/student_course/') #总页数 传入url
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— return render(request, 'bpm_student/student_course.html', locals()) #学生上课记录列表
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def studyrecords(request,enroll_obj_id):
enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#根据ID获取06学员报名信息表
studyrecordlist=enroll_obj.studyrecord_set.all()#根据06学员报名信息表的ID获取09学习纪录 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
page = Page(request.GET.get('p', 1), len(studyrecordlist)) #当前页数 默认为1 #总数量
studyrecordlist = studyrecordlist[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/studyrecords/%s/'%enroll_obj_id) #总页数 传入url
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— return render(request,'bpm_student/studyrecords.html',locals()) # ————————60PerfectCRM实现CRM学生上课记录———————— # ————————61PerfectCRM实现CRM学生上传作业————————
from django.contrib.auth.decorators import login_required #登陆才能访问
from PerfectCRM import settings #静态配置文件 #作业上传 # 上传路径
import os,json,time #系统操作
from django.shortcuts import HttpResponse #页面返回
from django.shortcuts import redirect #页面返回
#作业详情
@login_required#登陆才能访问
@check_permission #权限控制
def homework_detail(request,enroll_obj_id,studyrecord_id):
studyrecord_obj=models.StudyRecord.objects.get(id=studyrecord_id)#取学习记录 对象
enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#取班级对象 # 作业根目录 班级ID 上课记录ID 学习记录ID
homework_path="{base_dir}/{class_id}/{course_record_id}/{studyercord_id}/".format(
base_dir=settings.HOMEWORK_DATA, #静态配置文件
class_id=studyrecord_obj.student.enrolled_class_id,#09学习纪录#学生名字#所报班级ID号
course_record_id=studyrecord_obj.course_record_id,#09学习纪录#每节课上课纪录表
studyercord_id=studyrecord_obj.id##09学习纪录
)
print('homework_path路径:',studyrecord_obj.student.enrolled_class_id,studyrecord_obj.course_record_id,studyrecord_obj.id) if os.path.exists(homework_path):#判断目录是否存在
file_lists = [] # 已经上传的文件列表
for file_name in os.listdir( homework_path ):
f_path = '%s/%s' % (homework_path, file_name) # 文件名字
modify_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.gmtime( os.stat( f_path ).st_mtime ) ) # 文件上传时间
file_lists.append( [file_name, os.stat( f_path ).st_size, modify_time] ) # 添加到文件列表#文件名字#文件大小文件上传时间 if request.method=="POST":#上传
ret=False
data=request.POST.get('data') #ajax
if data:#如果有删除动作
del_f_path="%s/%s"%(homework_path,data)#文件路径
print('删除文件,路径:',del_f_path)
os.remove(del_f_path) #删除
ret=True
return HttpResponse(json.dumps(ret))#ret=False
if request.is_ajax(): # ajax上传图片 #异步提交
print("POST",request.POST)
if not os.path.isdir( homework_path ): # 没有目录 #isdir返回true,如果路径名是指现有的目录。
os.makedirs( homework_path, exist_ok=True ) # 创建目录  
for k,v in request.FILES.items():#上传的文件
with open('%s/%s'%(homework_path,v.name),'wb') as f:#chunk 写入文件
for chunk in v.chunks(): #循环写文件
f.write(chunk)
return HttpResponse( json.dumps( {"status": 0, 'mag': "上传完成!", 'file_lists': file_lists} ) ) # 上传文件返回 if request.method=="POST":#上传
link = request.POST.get( 'link' ) # 让页面POST提交的值,在页面GET后仍然存在显示
if link:
homework_link=models.StudyRecord.objects.filter( id=studyrecord_id ).update(homework_link=link)
return redirect('/bpm/homework_detail/%s/%s/' %(enroll_obj_id,studyrecord_id) )#跳转到enrollment_rejection
return render(request,'bpm_student/homework_detail.html',locals())
# ————————61PerfectCRM实现CRM学生上传作业————————

# student_views.py

 # teacher_views.py
# ————————62PerfectCRM实现CRM讲师讲课记录————————
from django.contrib.auth.decorators import login_required # 登陆后页面才能访问
from django.shortcuts import render #页面返回 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
from bpm.bpm_auxiliary.pagination import Page #分页
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
# 讲师班级
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def teacher_class(request):
# user_id=request.user.id #当前登陆的ID
# classlist=models.UserProfile.objects.get(id=user_id).classlist_set.all()#讲师所教班级
classes_obj = request.user.classlist_set.all() # 根据 登陆的ID 获取02班级表 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
page = Page(request.GET.get('p', 1), len(classes_obj)) #当前页数 默认为1 #总数量
classes_obj = classes_obj[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/teacher_class/') #总页数 传入url
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— return render( request, 'bpm_teacher/teacher_class.html', locals() ) # 讲师班级课节详情
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def teacher_class_detail(request, class_id):
# user_id=request.user.id #当前登陆的ID
# classes_obj=models.UserProfile.objects.get(id=user_id).classlist_set.get(id=class_id)#所选的班级
classes_obj = request.user.classlist_set.get( id=class_id ) # 根据 登陆的ID 获取02班级表
courserecordlist = classes_obj.courserecord_set.all() # 根据 02班级表的ID 获取09学习纪录 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
page = Page( request.GET.get( 'p', 1 ), len( courserecordlist ) ) # 当前页数 默认为1 #总数量
courserecordlist = courserecordlist[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/teacher_class_detail/%s/'%class_id) #总页数 传入url
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— return render( request, 'bpm_teacher/teacher_classes_detail.html', locals() )
# ————————62PerfectCRM实现CRM讲师讲课记录———————— # ————————63PerfectCRM实现CRM讲师下载作业————————
from PerfectCRM import settings # 系统配置
import os # 系统操作
# 本节课的学员
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def teacher_lesson_detail(request, class_id, courserecord_id):
# classes_obj=models.UserProfile.objects.get(id=request.user.id).classlist_set.get(id=class_id)#所选的班级
classes_obj = request.user.classlist_set.get( id=class_id ) # 根据 登陆的ID 获取02班级表
courserecordlist = classes_obj.courserecord_set.get( id=courserecord_id ) # 根据 前端的ID 获取08每节课上课纪录表 # studyrecord_list=models.CourseRecord.objects.get(id=courserecord_id).studyrecord_set.all()#取本节课所有学员
studyrecord_list = courserecordlist.studyrecord_set.all() # 根据08每节课上课纪录表 #获取09学习纪录 #取本节课所有学员 for i in studyrecord_list: # 循环本节课所有学员 交作业的状态
studyrecord_id = i.id # 获取本节课所有学员的ID
if studyrecord_id: # 有获取到ID
HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id) # 作业目录
if os.path.exists( HOMEWORK_path ): # 判断目录是否存在
try:#防止后台误删文件
file_list = os.listdir( HOMEWORK_path ) # 取目录 下的文件
isfile = os.path.isfile( '%s%s' % (HOMEWORK_path, file_list[0]) ) # 判断是不是文件
studyrecord_list.filter( id=studyrecord_id ).update( delivery=isfile ) # 更新交付作业状态
except:
studyrecord_list.filter( id=studyrecord_id ).update( delivery=False ) # file_list 出错# 更新交付作业状态
else:
studyrecord_list.filter( id=studyrecord_id ).update( delivery=False )# 更新交付作业状态 # ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页————————
page = Page( request.GET.get( 'p', 1 ), len( studyrecord_list ) ) # 当前页数 默认为1 #总数量
studyrecord_list = studyrecord_list[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/teacher_lesson_detail/%s/%s/'%(class_id,courserecord_id)) # 总页数 传入url
# ————————69PerfectCRM实现CRM业务流程(bpm)学生讲师分页———————— return render( request, 'bpm_teacher/teacher_lesson_detail.html', locals() ) from django.http import StreamingHttpResponse #页面返回
from crm import models #数据库
from django.shortcuts import redirect #页面返回
# 学员作业下载
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def howk_down(request, class_id, courserecord_id, studyrecord_id):
HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id) # 作业目录
print( '下载作业目录:', HOMEWORK_path ) def file_iterator(file_path, chunk_size=512): # 获取文件 #chunk_size每次读取的大小 #文件迭代器
with open( file_path, 'rb', ) as f: # 循环打开 文件#以二进制读模式打开
while True: # 如果有文件
byte = f.read( chunk_size ) # read读最多大小字节,作为字节返回。#获取文件大小
if byte:
yield byte # 返回 yield 后的值作为第一次迭代的返回值. 循环下一次,再返回,直到没有可以返回的。
else:
break # 没有字节就中止 if os.path.exists( HOMEWORK_path ): # 判断目录是否存在
try:#防止后台误删文件
file_list = os.listdir( HOMEWORK_path ) # 取目录 下的文件
print( '文件名:', file_list, type( file_list ) )
file_path = '%s%s' % (HOMEWORK_path, file_list[0]) # 下载文件路径
print( '下载文件路径:', file_path )
response = StreamingHttpResponse( file_iterator( file_path ) ) # StreamingHttpResponse是将文件内容进行流式传输
response['Content-Type'] = 'application/octet-stream' # 文件类型 #应用程序/octet-stream.*( 二进制流,不知道下载文件类型)
file_name = 'attachment;filename=%s' % file_list[0] # 文件名字# 支持中文
response['Content-Disposition'] = file_name.encode() # 支持中文#编码默认encoding='utf-8'
return response # 返回下载 请求的内容
except:
models.StudyRecord.objects.get( id=studyrecord_id ).update( delivery=False ) # 更新交付作业状态 # file_list 出错
return redirect( '/bpm/teacher_lesson_detail/%s/%s/' % (class_id, courserecord_id) ) # 返回##本节课的学员
# ————————63PerfectCRM实现CRM讲师下载作业————————

# teacher_views.py

 # coursetop_views.py
# ————————64PerfectCRM实现CRM课程排名详情————————
#————班级学生详情——#计算#{学员ID:分数}——#计算 #{学员ID: [分数, 排名] }————#
#班级学生详情#计算#{学员ID:分数}
from django.db.models import Sum #返回数组中所有值的和
def get_course_grades(class_obj):#返回整个班级的成绩
c=models.StudyRecord.objects.filter(course_record__from_class=class_obj).values_list('student')
a=Sum('score')#Sum返回数组中所有值的和 #学习成绩
e=c.annotate(a) #annotate数据库的数据聚合函数
class_grade_dic=dict(e)#{1: 285, 16: 190}#{学员ID:分数}
print( '全班成绩:', class_grade_dic)
return class_grade_dic #as class_grade_dic #班级学生详情#计算 #{学员ID: [分数, 排名] }
def get_course_ranking(class_grade_dic):#返回整个班级的排名数据
ranking_list = sorted(class_grade_dic.items(),key=lambda x:x[1],reverse=True)#进行排序后的列表#以第2个参数对比#倒序
print('成绩排序:',ranking_list)
ranking_dic = {}
for item in ranking_list:
ranking_dic[item[0]] = [item[1], ranking_list.index(item)+1] #循环添加 排名数 到 排序后的列表
print( '全班排名:', ranking_dic)#{1: [285, 1], 10: [280, 2], }#{学员ID: [分数, 排名] }
return ranking_dic
#————班级学生详情——#计算#{学员ID:分数}——#计算 #{学员ID: [分数, 排名] }————# from django.contrib.auth.decorators import login_required # 登陆后页面才能访问
from django.shortcuts import render #页面返回
from crm import models #数据库
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页————————
from bpm.bpm_auxiliary.pagination import Page #分页
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
from permissions.permission import check_permission #权限控制
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL———————— #班级学生详情
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def coursetop_details(request,class_id):
classes_obj = models.ClassList.objects.get(id=class_id)#通过ID获取02班级表
enrollmentlist=classes_obj.enrollment_set.all()#通过班级ID,获取06学员报名信息表 class_grade_dic=get_course_grades(classes_obj.id)#{学员ID:分数} #全班成绩 # coursetop_tags.py 根据id 找对应的分数
ranking_dic=get_course_ranking(class_grade_dic)#{学员ID: [分数, 排名] } #全班排名 # coursetop_tags.py 根据id 找对应的排名 # ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页————————
page = Page( request.GET.get( 'p', 1 ), len( enrollmentlist ) ) # 当前页数 默认为1 #总数量
enrollmentlist = enrollmentlist[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/coursetop_details/%s/'%(class_id)) # 总页数 传入url
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页———————— return render(request,'bpm_coursetop/coursetop_details.html',locals())
# ————————64PerfectCRM实现CRM课程排名详情———————— # ————————65PerfectCRM实现CRM课程分数排名————————
#———— 班级学生详情——#计算 #{排名: (ID, 分数)}#排名查名字————#
def get_ranking_name(class_grade_dic):
lists=[]
ranking_list = sorted(class_grade_dic.items(),key=lambda x:x[1],reverse=True)#进行排序后的列表#以第2个参数对比#倒序
#ranking_list [(1, 285), (10, 280)] #按分高排序的ID顺序
for item in ranking_list:
temp={}
temp[ranking_list.index(item) + 1] = item # 循环添加 排名数 到 排序后的列表
lists.append(temp)
print( '排名查名字:', lists )#[{1: (1, 285)}, {2: (10, 280)}]#[{排名: (学员ID, 分数)}]
return lists
#———— 班级学生详情——#计算 #{排名: (ID, 分数)}#排名查名字————# #班级学生详情#全班成绩排名 #通过#{排名: (ID, 分数)}#排名查名字
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def coursetop_score(request,class_id):
classes_obj = models.ClassList.objects.get(id=class_id)#通过ID获取02班级表
class_grade_dic=get_course_grades(classes_obj.id)#{学员ID:分数} #全班成绩
lists=get_ranking_name(class_grade_dic)#计算#[{排名: (学员ID, 分数)}] #按分高排序的ID顺序 # ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页————————
page = Page( request.GET.get( 'p', 1 ), len( lists ) ) # 当前页数 默认为1 #总数量
lists = lists[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/coursetop_score/%s/'%(class_id)) # 总页数 传入url
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页———————— return render(request,'bpm_coursetop/coursetop_score.html',locals()) # ————————65PerfectCRM实现CRM课程分数排名———————— # ————————66PerfectCRM实现CRM课程作业排名————————
#————#班级学生详情#计算#学员已交作业的数量————#
#班级学生详情#计算#学员已交作业的数量
def get_already_homework(class_id):
score_list = models.StudyRecord.objects.select_related().filter(student=class_id ).values_list( 'score' )#学习成绩
number = 0
for score in score_list:
if score != (0,): # (0,"N/A")
number += 1 #通过 学习成绩 不等于0 计算#已交作业的数量
return number
#————#班级学生详情#计算#学员已交作业的数量————# #班级学生详情#学员已交作业的数量#作业查名字
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def coursetop_homework(request,class_id):
classes_obj = models.ClassList.objects.get(id=class_id)#通过ID获取02班级表
class_grade_dic=get_course_grades(classes_obj.id)#{学员ID:分数} #全班成绩
ranking_dic=get_course_ranking(class_grade_dic)#{学员ID: [分数, 排名] } #全班排名
enrollmentlist=classes_obj.enrollment_set.all()#通过班级ID,获取06学员报名信息表 dict = {}#{1: 3, 4: 2,}#{学员ID: 数量}
for item in enrollmentlist:
d = get_already_homework( item.id )#根据06学员报名信息表#学员ID #计算#学员已交作业的数量
dict[item.id]= d list = sorted(dict.items(),key=lambda x:x[1])#进行排序后的列表#以第2个参数对比
#list[ (4, 2), (16, 2)] #list[ (学员ID, 数量)] lists=[] #[{1: (19, 0)}, {2: (20, 0)}]#[{排名: (学员ID, 数量)}]
for item in list:
temp={}
temp[list.index( item ) + 1] = item # 循环添加 排名数 到 排序后的列表 #按已交作业数量少到多排序
lists.append(temp)
print('已交作业:',lists) # ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页————————
page = Page( request.GET.get( 'p', 1 ), len( lists ) ) # 当前页数 默认为1 #总数量
lists = lists[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/coursetop_homework/%s/'%(class_id)) # 总页数 传入url
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页———————— return render(request,'bpm_coursetop/coursetop_homework.html',locals())
# ————————66PerfectCRM实现CRM课程作业排名———————— # ————————67PerfectCRM实现CRM课程出勤排名————————
#————#班级学生详情#学员出勤次数 #出勤次数查名字————#
#班级学生详情#计算#学员出勤次数
def get_stu_attendance(enroll_obj_id):
attendance_list=models.StudyRecord.objects.select_related().filter(student=enroll_obj_id).values_list('attendance')
number=0
for attendance in attendance_list:
if attendance == (0,) :
number += 1
return number
#————#班级学生详情#学员出勤次数 #出勤次数查名字————# #班级学生详情#学员出勤次数 #出勤次数查名字
@login_required # 登陆后页面才能访问
@check_permission #权限控制
def coursetop_attendance(request,class_id):
classes_obj = models.ClassList.objects.get(id=class_id)#通过ID获取02班级表
class_grade_dic=get_course_grades(classes_obj.id)#{学员ID:分数} #全班成绩
ranking_dic=get_course_ranking(class_grade_dic)#{学员ID: [分数, 排名] } #全班排名
enrollmentlist=classes_obj.enrollment_set.all()#通过班级ID,获取06学员报名信息表 dict = {} #{1: 3, 4: 2,}#{学员ID: 次数}
for item in enrollmentlist:
d = get_stu_attendance( item.id )#根据06学员报名信息表#学员ID #计算#学员学员出勤次数
dict[item.id]= d # 循环添加 {学员ID: 次数} #排序后的字典 list = sorted(dict.items(),key=lambda x:x[1])#进行排序后的列表#以第2个参数对比 #按出勤次数少到多排序
#list[ (4, 2), (16, 2)] #list[ (学员ID, 次数)] lists=[]#[{1: (19, 3)}, {2: (20, 1)}]#[{排名: (学员ID, 次数)}]
for item in list:
temp={}
temp[list.index( item ) + 1] = item # 循环添加 排名数 #排序后的列表
lists.append(temp)
print('全班出勤',lists) # ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页————————
page = Page( request.GET.get( 'p', 1 ), len( lists ) ) # 当前页数 默认为1 #总数量
lists = lists[page.start:page.end] # 切片取当前页的数据
page_str = page.page_str('/bpm/coursetop_attendance/%s/'%(class_id)) # 总页数 传入url
# ————————70PerfectCRM实现CRM业务流程(bpm)课程排行分页———————— return render(request,'bpm_coursetop/coursetop_attendance.html',locals())
# ————————67PerfectCRM实现CRM课程出勤排名————————

# coursetop_views.py

 # kingadmin.py
# ————————04PerfectCRM实现King_admin注册功能————————
from crm import models
#print("kingadmin crm",models.Customer) # ————————05PerfectCRM实现King_admin注册功能获取内存————————
# from king_admin.base_admin import register,BaseAdmin
from king_admin.base_admin import site,BaseAdmin
# ————————05PerfectCRM实现King_admin注册功能获取内存———————— # ————————24PerfectCRM实现King_admin自定义操作数据————————
from django.shortcuts import render
# ————————24PerfectCRM实现King_admin自定义操作数据———————— # ————————28PerfectCRM实现King_admin编辑限制————————
from django.forms import ValidationError
from django.shortcuts import render,redirect
# ————————28PerfectCRM实现King_admin编辑限制———————— # ————————62PerfectCRM实现CRM讲师讲课记录————————
# 02班级表
class ClassListAdmin(BaseAdmin):
list_display = ['id', 'branch', 'course', 'class_type', 'semester', 'start_date', 'end_date'] # 显示字段表头
list_filter = ['branch', 'course', 'class_type'] # 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
filter_horizontal = ['teachers'] #复选框
site.register(models.ClassList,ClassListAdmin) #02班级表 # ————————62PerfectCRM实现CRM讲师讲课记录———————— #04客户信息表
class CustomerAdmin(BaseAdmin):#定制Djanago admin
# ————————54PerfectCRM实现CRM客户报名链接————————
# list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date') # 显示字段表头
list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date','status','enroll') # 显示字段表头
# ————————54PerfectCRM实现CRM客户报名链接————————
# ————————11PerfectCRM实现King_admin分页显示条数————————
list_per_page = 2 #分页条数 # 默认分页条数10
# ————————11PerfectCRM实现King_admin分页显示条数————————
# ————————16PerfectCRM实现King_admin日期过滤————————
# ————————15PerfectCRM实现King_admin多条件过滤————————
# 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
# list_filter = ('source','consultant','consult_courses',)
list_filter = ('date','source','consultant','consult_courses',)
# ————————15PerfectCRM实现King_admin多条件过滤————————
# ————————16PerfectCRM实现King_admin日期过滤————————
# ————————18PerfectCRM实现King_admin搜索关键字————————
#搜索(不能包含CharField)(注意加 逗号 , )
search_fields = ('name','qq',)
# ————————18PerfectCRM实现King_admin搜索关键字————————
# ————————26PerfectCRM实现King_admin自定义排序————————
ordering = '-qq' #自定义排序,默认'-id'
# ————————26PerfectCRM实现King_admin自定义排序————————
# ————————27PerfectCRM实现King_admin编辑复选框————————
filter_horizontal = ('tags',) #复选框
# ————————27PerfectCRM实现King_admin编辑复选框————————
# ————————33PerfectCRM实现King_admin编辑整张表限制————————
readonly_table=True#默认表单不锁定
# ————————33PerfectCRM实现King_admin编辑整张表限制———————— # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
colored_fields = {
'status':{'已报名':"rgba(145, 255, 0, 0.78)",
'未报名':"#ddd"},}
# ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— # ————————54PerfectCRM实现CRM客户报名链接————————
def enroll(self):
'''报名'''
print("customize field enroll",self)
link_name = "报名"
if self.instance.status == 0:
link_name = "报名新课程"
return '''<a target="_blank" class="btn-link" href="/bpm/customer/%s/enrollment/">点击%s</a> ''' % (self.instance.id,link_name)
# url(r'^customer/(\d+)/enrollment/$', sales_views.enrollment, name="enrollment"), # 客户招生#报名流程一 下一步
# target属性用于表示所链接文件打开到的位置 #记住,“”内的文字只是表示一个对象的名子。
enroll.display_name = "报名链接"
# ————————54PerfectCRM实现CRM客户报名链接———————— # ————————24PerfectCRM实现King_admin自定义操作数据————————
# from django.shortcuts import render
actions = ['test_actions',]#定制功能 #测试返回到一个新页面
def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容
return render(request,"king_admin/table_index.html")
test_actions.short_description = "测试显示中文"
# ————————24PerfectCRM实现King_admin自定义操作数据———————— # ————————28PerfectCRM实现King_admin编辑限制————————
# ————————31PerfectCRM实现King_admin编辑多对多限制————————
# readonly_fields = ('qq', 'consultant',) # 不可修改
readonly_fields = ('qq', 'consultant','tags',) # 不可修改
# ————————31PerfectCRM实现King_admin编辑多对多限制———————— # ————————29PerfectCRM实现King_admin编辑自定义限制————————
def default_form_validation(self,obj):
print('validation:制定的',obj.cleaned_data)
consult_course=obj.cleaned_data.get('content','')#自制验证字段
if len(consult_course)<10:
return ValidationError(#添加错误信息 返回
("该字段%(field)s 咨询内容记录不能少于10个字符"),
code='invalid',
params={'field':'content',},
)
# ————————29PerfectCRM实现King_admin编辑自定义限制———————— # ————————28PerfectCRM实现King_admin编辑限制———————— # ————————30PerfectCRM实现King_admin编辑自定义字段验证————————
def clean_name(self,obj,*args,**kwargs):#名称验证 单个
name=obj.cleaned_data['name']
if not name:
obj.add_error('name','不能为空!')
return ValidationError(#添加错误信息 返回
("%(field)s:该字段 不能为空"),
code='invalid',
params={'field':'name',},
)
elif len(name)<5:
obj.add_error('name','不能小于5个字符!')
#return ValidationError('',)
return ValidationError(#添加错误信息 返回
("%(field)s:该字段 不能小于5个字符!"),
code='invalid',
params={'field':'name',},
)
# ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— # ————————34PerfectCRM实现CRM自定义用户————————
#10账号表
class UserProfileAdmin(BaseAdmin):#定制Djanago admin
list_display = ('id', 'email', 'name') # 显示字段表头 # ————————36PerfectCRM实现King_admin密码修改————————
readonly_fields = ('password',) # 不可修改,限制 # ————————72PerfectCRM实现CRM动态菜单和角色————————
# filter_horizontal = ('user_permissions','groups') #复选框
filter_horizontal = ('user_permissions', 'groups','roles') # 复选框
# ————————72PerfectCRM实现CRM动态菜单和角色———————— modelform_exclude_fields=['last_login']#排除#不显示 #自增日期 #base_admin.py #forms.py
# ————————36PerfectCRM实现King_admin密码修改———————— site.register(models.UserProfile, UserProfileAdmin)
# ————————34PerfectCRM实现CRM自定义用户———————— # ————————05PerfectCRM实现King_admin注册功能获取内存————————
# register(models.Customer,CustomerAdmin)
# register(models.CourseRecord)
site.register(models.Customer,CustomerAdmin)
# ————————58PerfectCRM实现king_admin批量生成上课记录————————
# site.register(models.CourseRecord)
# ————————58PerfectCRM实现king_admin批量生成上课记录————————
# ————————05PerfectCRM实现King_admin注册功能获取内存———————— # ————————04PerfectCRM实现King_admin注册功能———————— # ————————56PerfectCRM实现CRM客户报名缴费链接————————
# 06学员报名信息表
class EnrollmentAdmin(BaseAdmin): # 定制Djanago admin
list_display = ('id', 'customer', 'enrolled_class', 'consultant', 'Pay_cost', 'date', 'payment') # 显示字段表头 # ————————58PerfectCRM实现king_admin批量生成上课记录————————
list_filter = ('enrolled_class','consultant', 'Pay_cost',) # 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
# ————————58PerfectCRM实现king_admin批量生成上课记录———————— colored_fields = {
'Pay_cost': {True: "rgba(145, 255, 0, 0.78)",
False: "#ddd"}, }
def payment(self):
link_name = "增加缴费"
if self.instance.Pay_cost == False:
link_name = "缴费"
return '''<a target="_blank" class="btn-link" href="/bpm/payment/%s/" >点击%s</a> ''' % (self.instance.id, link_name)
# url(r'^payment/(\d+)/$', financial_views.payment, name="payment"), # 报名流程四 缴费 #财务
# target属性用于表示所链接文件打开到的位置 #记住,“”内的文字只是表示一个对象的名子。
payment.display_name = "缴费链接"
site.register(models.Enrollment, EnrollmentAdmin) # 06学员报名信息表
# ————————56PerfectCRM实现CRM客户报名缴费链接———————— # ————————58PerfectCRM实现king_admin批量生成上课记录————————
# 07缴费记录表
class PaymentAdmin(BaseAdmin):
list_display = ['id', 'customer', 'course', 'amount', 'consultant','date'] # 显示字段表头
list_filter = ('customer', 'course', 'consultant',) # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) from django.shortcuts import render, HttpResponse, redirect
# 08每节课上课纪录表
class CourseRecordAdmin(BaseAdmin):
list_display = ['id', 'from_class', 'day_num', 'teacher', 'has_homework', 'homework_title', 'homework_content','outline', 'date'] # 显示字段表头
list_filter = ('from_class', 'teacher', 'date') # 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
def initialize_studyrecords(self, request, queryset): # 制定功能
print('initialize_studyrecords', self, request, queryset)
if len(queryset) > 1:
return HttpResponse("同时只能选择一个班级!")
print('获取对应的学员', queryset[0].from_class.enrollment_set.all()) # _set反向查询
new_obj_list = [] # 用于批量创建事务 #防止数据库事物回滚
for enrll_obj in queryset[0].from_class.enrollment_set.all(): # 创建学习记录
# models.StudyRecord.objects.get_or_create( #get_or_ #防止报错
# student=enrll_obj,#对应学员
# course_record=queryset[0],
# attendance=0,#签到状态,默认签到,
# score=0,#成绩
# ) # 防止数据库事物回滚 #"""09学习纪录"""
new_obj_list.append(models.StudyRecord(
student=enrll_obj, # 对应学员
course_record=queryset[0], # 班级#节课
attendance=0, # 签到状态,默认签到,
score=0, # 成绩
))
try:
models.StudyRecord.objects.bulk_create(new_obj_list) # bulk_create批量创建数据库事物 #统一最后保存
except Exception as e:
return HttpResponse('批量创建失败,本节课可能有相应的上课记录') return redirect("/king_admin/crm/studyrecord/?course_record=%s" % queryset[0].id) # 学习记录 #加上过滤 actions = ['initialize_studyrecords', ]
initialize_studyrecords.short_description = "创建班级本节上课记录" # 显示别名
# 09学习纪录
class StudyRecordAdmin(BaseAdmin):
list_display = ['id', 'student', 'course_record', 'attendance', 'score', 'date'] # 显示字段表头 list_filter = ['course_record', 'attendance', 'score', 'student'] # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) list_editable = ['score', 'attendance'] # 可编辑 #用于上课点名 批改成绩 site.register(models.Payment, PaymentAdmin) # 07缴费记录表
site.register(models.CourseRecord, CourseRecordAdmin) # 08每节课上课纪录表
site.register(models.StudyRecord, StudyRecordAdmin) # 09学习纪录
# ————————58PerfectCRM实现king_admin批量生成上课记录———————— # ————————72PerfectCRM实现CRM动态菜单和角色————————
# 11角色表
class RoleAdmin(BaseAdmin):
list_display = ['id', 'name'] # 显示字段表头
filter_horizontal = ['menus'] # 复选框
site.register(models.Role,RoleAdmin) #11角色表 # 13一层菜单名
class FirstLayerMenuAdmin(BaseAdmin):
list_display = ['id', 'name', 'url_type', 'url_name', 'order'] # 显示字段表头
site.register(models.FirstLayerMenu,FirstLayerMenuAdmin) #13一层菜单名
# 14二层菜单名
class SubMenuMenuAdmin(BaseAdmin):
list_display = ['id', 'name', 'url_type', 'url_name', 'order'] # 显示字段表头
site.register(models.SubMenu,SubMenuMenuAdmin) #14二层菜单名
# ————————72PerfectCRM实现CRM动态菜单和角色———————— # ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————
class GroupsAdmin(BaseAdmin):
list_display = ['id', 'name'] # 显示字段表头
filter_horizontal = ['permissions'] # 复选框
site.register(models.Groups,GroupsAdmin) #14二层菜单名
# ————————74PerfectCRM实现CRM权限和权限组限制访问URL————————

# kingadmin.py


如果感觉本章博客对您有帮助,请尽情打赏吧!

Django项目:CRM(客户关系管理系统)--84--74PerfectCRM实现CRM权限和权限组限制访问URL的更多相关文章

  1. Django CRM客户关系管理系统

    CRM需求分析 随着信息化时代带来的科技创新,CRM客户关系管理系统带来的效益在已经成为很多企业提高竞争优势的一分部,CRM客户关系管理系统将企业管理和客户关系管理集成到统一的平台,其系统功能主要体现 ...

  2. Django项目:CRM(客户关系管理系统)--85--75PerfectCRM实现CRM扩展权限

    # sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...

  3. Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  4. Django项目:CRM(客户关系管理系统)--74--64PerfectCRM实现CRM课程排名详情

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  5. Django项目:CRM(客户关系管理系统)--72--62PerfectCRM实现CRM讲师讲课记录

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  6. CRM 客户关系管理系统

    CRM(Customer Relationship Manager)客户关系管理系统 企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方 ...

  7. CRM客户关系管理系统-需求概设和详设

    大概设计 大概设计就是对需求进行一个整体性分析,把需要实现的功能都列出来,对于客户关系管理系统,我们需要从角色出发,从而确定有哪些需求,最好是画个思维导图 首先我们是为培训学校这么一个场景来开发的,所 ...

  8. CRM客户关系管理系统 北京易信软科信息技术有限公司

    北京易信软科信息技术有限公司 推出大型erp系统,库存管理系统,客户关系管理系统,车辆登记管理系统,员工管理系统,采购管理系统,销售管理系统,为您的企业提供最优质的产品服务 北京易信软科您可信赖的北京 ...

  9. Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

随机推荐

  1. linux软件包rpm的使用

    一rpm包管理器 (一)rpm的介绍 rpm不仅是文件的后缀,也是一个工具,外部命令,程序包管理器 功能:将编译好的应用程序的各组成文件打包一个或几个程序包文件,从而方便快捷地实现程序包的安装.卸载. ...

  2. spring整合hibernate之买书小测试

    spring来整合hibernate就是用spring来管理hibernate的sessionFactory和让hibernate来使用spring的声明式事务. 一:加入相应的jar包. 二:写hi ...

  3. [CSP-S模拟测试]:蛋糕(区间DP)

    题目传送门(内部题34) 输入格式 第一行,一个正整数$n$.第二行,$n$个正整数$a_i$,保证$a_i$互不相等. 输出格式 一行一个整数表示间宫卓司得到的蛋糕大小总和的最大值. 样例 样例输入 ...

  4. 升级到Xcode 5.1和iOS 7遇到的各种问题及解决办法汇总:

    <iOS 企业证书部署无效的问题>:http://t.cn/8s7ILWZ <clipsToBounds 属性默认值变了>:http://weibo.com/165881473 ...

  5. 《ArcGIS Runtime SDK for .NET开发笔记》--在线编辑

    介绍 ArcGIS可以发布具有编辑功能的Feature Service.利用Feature Service我们可以实现对数据的在线编辑. 数据制作参考: https://server.arcgis.c ...

  6. cs224d 作业 problem set2 (二) TensorFlow 实现命名实体识别

    神经网络在命名实体识别中的应用 所有的这些包括之前的两篇都可以通过tensorflow 模型的托管部署到 google cloud 上面,发布成restful接口,从而与任何的ERP,CRM系统集成. ...

  7. django 重写 mysql 连接库实现连接池

    django 重写 mysql 连接库实现连接池 问题 django 项目使用 gunicorn + gevent 部署,并设置 CONN_MAX_AGE 会导致 mysql 数据库连接数飙升,在高并 ...

  8. upc组队赛14 Evolution Game【dp】

    Evolution Game 题目描述 In the fantasy world of ICPC there are magical beasts. As they grow, these beast ...

  9. Java异常处理教程

    异常是在没有定义正常执行路径时在Java程序的执行期间可能出现的条件.Java通过将执行操作的代码与处理错误的代码分离来处理错误. 当发生异常时,Java会创建一个包含有关异常的所有信息的对象,并将其 ...

  10. Java DOM解析器 - 查询XML文档

    这是需要我们查询的输入XML文件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0"?> ...