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

时间:2023-12-04 19:28:26

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

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

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

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

 #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

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

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

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

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

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

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

 # 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

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

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

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

 # 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

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

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

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

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

 # 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

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

 # 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

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

 # 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

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

 # 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

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

 # 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

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

 # 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

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

 # 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

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

 # 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

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

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


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

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