Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业

 1 # teacher_urls.py
 2 # ————————62PerfectCRM实现CRM讲师讲课记录————————
 3 from django.conf.urls import url
 4 from bpm.teacher import teacher_views
 5 urlpatterns = [
 6     url(r'^teacher_class/$', teacher_views.teacher_class,name='teacher_class'),#讲师班级
 7     url(r'^teacher_class_detail/(d+)/$', teacher_views.teacher_class_detail, name='teacher_class_detail'),  # 讲师班级课节详情
 8 
 9     # ————————63PerfectCRM实现CRM讲师下载作业————————
10     url( r'^teacher_lesson_detail/(d+)/(d+)/$', teacher_views.teacher_lesson_detail,name='teacher_lesson_detail' ),  # 本节课的学员
11     url( r'^homeworks/(d+)/(d+)/(d+)/$', teacher_views.howk_down, name='howk_down' ),  # 作业下载
12     # ————————63PerfectCRM实现CRM讲师下载作业————————
13 ]
14 
15 # ————————62PerfectCRM实现CRM讲师讲课记录————————
# teacher_urls.py

 1 # teacher_views.py
 2 # ————————62PerfectCRM实现CRM讲师讲课记录————————
 3 from django.contrib.auth.decorators import login_required  # 登陆后页面才能访问
 4 from django.shortcuts import render  #页面返回
 5 # 讲师班级
 6 @login_required  # 登陆后页面才能访问
 7 def teacher_class(request):
 8     # user_id=request.user.id #当前登陆的ID
 9     # classlist=models.UserProfile.objects.get(id=user_id).classlist_set.all()#讲师所教班级
10     classes_obj = request.user.classlist_set.all()  # 根据 登陆的ID 获取02班级表
11     return render( request, 'bpm_teacher/teacher_class.html', locals() )
12 
13 # 讲师班级课节详情
14 @login_required  # 登陆后页面才能访问
15 def teacher_class_detail(request, class_id):
16     # user_id=request.user.id #当前登陆的ID
17     # classes_obj=models.UserProfile.objects.get(id=user_id).classlist_set.get(id=class_id)#所选的班级
18     classes_obj = request.user.classlist_set.get( id=class_id )  # 根据 登陆的ID 获取02班级表
19     courserecordlist = classes_obj.courserecord_set.all()  # 根据 02班级表的ID 获取09学习纪录
20     return render( request, 'bpm_teacher/teacher_classes_detail.html', locals() )
21 # ————————62PerfectCRM实现CRM讲师讲课记录————————
22 
23 # ————————63PerfectCRM实现CRM讲师下载作业————————
24 from PerfectCRM import settings  # 系统配置
25 import os  # 系统操作
26 # 本节课的学员
27 @login_required  # 登陆后页面才能访问
28 def teacher_lesson_detail(request, class_id, courserecord_id):
29     # classes_obj=models.UserProfile.objects.get(id=request.user.id).classlist_set.get(id=class_id)#所选的班级
30     classes_obj = request.user.classlist_set.get( id=class_id ) # 根据 登陆的ID 获取02班级表
31     courserecordlist = classes_obj.courserecord_set.get( id=courserecord_id )  # 根据 前端的ID 获取08每节课上课纪录表
32 
33     # studyrecord_list=models.CourseRecord.objects.get(id=courserecord_id).studyrecord_set.all()#取本节课所有学员
34     studyrecord_list = courserecordlist.studyrecord_set.all()  # 根据08每节课上课纪录表 #获取09学习纪录 #取本节课所有学员
35 
36     for i in studyrecord_list:  # 循环本节课所有学员 交作业的状态
37         studyrecord_id = i.id  # 获取本节课所有学员的ID
38         if studyrecord_id:  # 有获取到ID
39             HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id)  # 作业目录
40             if os.path.exists( HOMEWORK_path ):  # 判断目录是否存在
41                 try:#防止后台误删文件
42                     file_list = os.listdir( HOMEWORK_path )  # 取目录 下的文件
43                     isfile = os.path.isfile( '%s%s' % (HOMEWORK_path, file_list[0]) )  # 判断是不是文件
44                     studyrecord_list.filter( id=studyrecord_id ).update( delivery=isfile )  # 更新交付作业状态
45                 except:
46                     studyrecord_list.filter( id=studyrecord_id ).update( delivery=False )  # file_list 出错# 更新交付作业状态
47             else:
48                 studyrecord_list.filter( id=studyrecord_id ).update( delivery=False )# 更新交付作业状态
49     return render( request, 'bpm_teacher/teacher_lesson_detail.html', locals() )
50 
51 from django.http import StreamingHttpResponse #页面返回
52 from crm import models #数据库
53 from django.shortcuts import redirect #页面返回
54 # 学员作业下载
55 @login_required  # 登陆后页面才能访问
56 def howk_down(request, class_id, courserecord_id, studyrecord_id):
57     HOMEWORK_path = '%s/%s/%s/%s/' % (settings.HOMEWORK_DATA, class_id, courserecord_id, studyrecord_id)  # 作业目录
58     print( '下载作业目录:', HOMEWORK_path )
59 
60     def file_iterator(file_path, chunk_size=512):  # 获取文件 #chunk_size每次读取的大小 #文件迭代器
61         with open( file_path, 'rb', ) as f:  # 循环打开 文件#以二进制读模式打开
62             while True:  # 如果有文件
63                 byte = f.read( chunk_size )  # read读最多大小字节,作为字节返回。#获取文件大小
64                 if byte:
65                     yield byte  # 返回 yield 后的值作为第一次迭代的返回值. 循环下一次,再返回,直到没有可以返回的。
66                 else:
67                     break  # 没有字节就中止
68 
69     if os.path.exists( HOMEWORK_path ):  # 判断目录是否存在
70         try:#防止后台误删文件
71             file_list = os.listdir( HOMEWORK_path )  # 取目录 下的文件
72             print( '文件名:', file_list, type( file_list ) )
73             file_path = '%s%s' % (HOMEWORK_path, file_list[0])  # 下载文件路径
74             print( '下载文件路径:', file_path )
75             response = StreamingHttpResponse( file_iterator( file_path ) )  # StreamingHttpResponse是将文件内容进行流式传输
76             response['Content-Type'] = 'application/octet-stream'  # 文件类型 #应用程序/octet-stream.*( 二进制流,不知道下载文件类型)
77             file_name = 'attachment;filename=%s' % file_list[0]  # 文件名字# 支持中文
78             response['Content-Disposition'] = file_name.encode()  # 支持中文#编码默认encoding='utf-8'
79             return response  # 返回下载 请求的内容
80         except:
81             models.StudyRecord.objects.get( id=studyrecord_id ).update( delivery=False )  # 更新交付作业状态 # file_list 出错
82     return redirect( '/bpm/teacher_lesson_detail/%s/%s/' % (class_id, courserecord_id) )  # 返回##本节课的学员
83 # ————————63PerfectCRM实现CRM讲师下载作业————————
# teacher_views.py

  1 #models.py
  2 
  3 # ————————01PerfectCRM基本配置ADMIN————————
  4 
  5 from django.db import models
  6 # Create your models here.
  7 
  8 """
  9 #运行 Terminal
 10 #    生成 数据表
 11 #    python manage.py makemigrations
 12 #   数据表 迁移
 13 #    python manage.py migrate
 14 """
 15 
 16 """01校区表"""
 17 class Branch(models.Model):
 18     name = models.CharField(max_length=128,unique=True) #校区名#CharField作用是保存文本,定长的变量类型
 19     addr = models.CharField(max_length=128) #地址
 20     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
 21         return self.name #返回 #校区名
 22     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
 23         verbose_name_plural =  "01校区表" #verbose_name_plural给你的模型类起一个更可读的名字
 24 
 25 """02班级表"""
 26 class ClassList(models.Model):
 27     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
 28     branch = models.ForeignKey("Branch",on_delete=models.CASCADE)#校区    关联到  校区表
 29     course = models.ForeignKey("Course",on_delete=models.CASCADE) #课程   关联到   课程表
 30 
 31     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
 32     contract = models.ForeignKey('ContractTemplate', blank=True, null=True, default=1,on_delete=models.CASCADE)  # 合同表
 33     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
 34 
 35     class_type_choices = ( #上课形式
 36                           (0,'面授(脱产)'),
 37                           (1,'面授(周末)'),
 38                           (2,'网络班'),)
 39     #PositiveSmallIntegerField正小整数 0 ~ 32767 #choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
 40     class_type = models.SmallIntegerField(choices=class_type_choices)#上课形式
 41 
 42     #PositiveSmallIntegerField正小整数 0 ~ 32767
 43     semester = models.PositiveSmallIntegerField(verbose_name="学期") #课程的第几期
 44 
 45     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
 46     teachers = models.ManyToManyField("UserProfile") # 老师   关联到    账号表
 47 
 48     start_date = models.DateField(verbose_name="开班日期") #DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称
 49 
 50     # DateField 日期格式 YYYY-MM-DD #verbose_name是Admin中显示的字段名称 #Django可空#数据库可以为空
 51     end_date = models.DateField(verbose_name="结业日期",blank=True,null=True)
 52 
 53     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
 54         return "%s %s %s" %(self.branch,self.course,self.semester) #返回 #%s格式化输出字符串 #校区#课程# 学期
 55     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
 56         unique_together=('branch','course','semester')  #联合索引
 57         verbose_name_plural = "02班级表" #verbose_name_plural给你的模型类起一个更可读的名字
 58 
 59 """03课程表,可以报名那些课程"""
 60 class Course(models.Model):
 61     name = models.CharField(max_length=64,unique=True)#课程名 #CharField作用是保存文本,定长的变量类型
 62     price = models.PositiveSmallIntegerField(verbose_name="学费")#学费#PositiveSmallIntegerField正小整数 0 ~ 32767
 63     period = models.PositiveSmallIntegerField(verbose_name="周期(月)") #PositiveSmallIntegerField正小整数 0 ~ 32767
 64     outline = models.TextField() #课程大纲  #文本类型
 65     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
 66         return self.name #返回 #课程名
 67     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
 68         verbose_name_plural =  "03课程表"#verbose_name_plural给你的模型类起一个更可读的名字
 69 
 70 '''04客户信息表'''
 71 class Customer(models.Model):
 72     name = models.CharField(max_length=32,blank=True,null=True)#客户名#CharField定长文本 #名字最长32 # Django可空 #数据库可以为空
 73     qq = models.CharField(max_length=64,unique=True) #QQ号#CharField定长文本 #名字最长64 #唯一,不能重复
 74     qq_name = models.CharField(max_length=64,blank=True,null=True)#QQ名 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
 75     phone = models.CharField(max_length=64,blank=True,null=True)#手机号 #CharField定长文本 #名字最长64 # Django可空 #数据库可以为空
 76 
 77     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
 78     id_num=models.CharField(max_length=64,blank=True,null=True,verbose_name='身份证号')#身份证号
 79     email=models.EmailField(max_length=64,blank=True,null=True,verbose_name='邮箱')#email
 80     sex_choices=((0,'保密'),(1,''),(2,''))
 81     sex=models.SmallIntegerField(choices=sex_choices,default=0,verbose_name='性别')
 82     # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
 83 
 84     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
 85     status_choices = ((0, '已报名'), (1, '未报名'), (2, '已退学'))
 86     status = models.SmallIntegerField(choices=status_choices, default=1)  # 学员状态
 87     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
 88 
 89     source_choices = ( #客户渠道来源 (内存生成)
 90                       (0,'转介绍'),
 91                       (1,'QQ群'),
 92                       (2,'官网'),
 93                       (3,'百度推广'),
 94                       (4,'51CTO'),
 95                       (5,'知乎'),
 96                       (6,'市场推广'),)
 97     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
 98     source = models.SmallIntegerField(choices=source_choices)#客户渠道来源
 99 
100     #CharField定长文本#verbose_name是Admin中显示的字段名称#名字最长64 # Django可空 #数据库可以为空
101     referral_from = models.CharField(verbose_name="转介绍人qq",max_length=64,blank=True,null=True) #来自谁介绍的
102 
103     #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
104     consult_courses = models.ForeignKey("Course",verbose_name="咨询课程", on_delete=models.CASCADE) #关联到 课程表
105 
106     content= models.TextField(verbose_name="咨询详情") #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
107 
108     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。
109     tags = models.ManyToManyField("Tag",blank=True)#多对多关联到 标签表
110 
111     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
112     consultant = models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到  账号表
113 
114     memo = models.TextField(blank=True,null=True)#备注#TextField无限制长度的文本#Django可空#数据库可以为空
115 
116     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
117     date =  models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
118 
119     def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
120         return self.qq  #返回 #QQ号
121 
122     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
123         verbose_name_plural =  "04客户表" #verbose_name_plural给你的模型类起一个更可读的名字
124 
125 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
126 #合同模版
127 class ContractTemplate(models.Model):
128     name=models.CharField('合同名称',max_length=64,unique=True)
129     template=models.TextField()
130 
131     def __str__(self):
132         return self.name
133     class Meta:
134         verbose_name_plural='合同表'
135 # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
136 
137 
138 """05客户跟进表"""
139 class CustomerFollowUp(models.Model):
140 
141     #ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
142     customer = models.ForeignKey("Customer", on_delete=models.CASCADE)#客户名 #关联到  客户信息表
143 
144     content = models.TextField(verbose_name="跟进内容")#跟进的内容#TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
145 
146     #ForeignKey就是表与表之间的某种约定的关系  #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
147     consultant =models.ForeignKey("UserProfile", on_delete=models.CASCADE) #关联到  账号表
148 
149     intention_choices =(  #报名状态
150                         (0,'2周内报名'),
151                         (1,'1个月内报名'),
152                         (2,'近期无报名计划'),
153                         (3,'已在其它机构报名'),
154                         (4,'已报名'),
155                         (5,'已拉黑'),)
156     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
157     intention=models.SmallIntegerField(choices=intention_choices) #报名状态
158 
159     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
160     date =  models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
161 
162     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
163         return "<%s:%s>" %(self.customer.qq,self.intention) #返回#格式化字符串#跨表里的QQ号#报名状态
164     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
165         verbose_name_plural =  "05客户跟进表"#verbose_name_plural给你的模型类起一个更可读的名字
166 
167 """06学员报名信息表"""
168 class Enrollment(models.Model):
169     # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
170     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字 #关联到  客户信息表
171     enrolled_class = models.ForeignKey("ClassList",verbose_name="所报班级",on_delete=models.CASCADE)#关联到  班级表
172     consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE) #关联到  账号表
173 
174     # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
175     contract_review = models.CharField(max_length=256, blank=True, null=True, verbose_name="合同审核")  # 合同审核
176     # ————————52PerfectCRM实现CRM客户报名流程学生合同审核————————
177 
178     #BooleanField布尔值类型#default=False默认(True)不允许出现空字符#verbose_name是Admin中显示的字段名称
179     contract_agreed = models.BooleanField(default=False,verbose_name="学员已经同意合同")#学员看合同
180     contract_approved = models.BooleanField(default=False,verbose_name="合同已经审核") #谁审核
181 
182     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
183     Pay_cost= models.BooleanField(default=False,verbose_name="缴费") #缴费状态#是不是交定金
184     # ————————53PerfectCRM实现CRM客户报名流程缴费————————
185 
186     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
187     date = models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
188 
189     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
190         # ————————57PerfectCRM实现admin批量生成上课记录————————
191         # return "%s %s" %(self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
192         return " 学员:%s |QQ: %s |班级:%s" %(self.customer.name,self.customer,self.enrolled_class)#返回#格式化字符串#学员名字#所报班级
193         # ————————57PerfectCRM实现admin批量生成上课记录————————
194     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
195         unique_together =  ("customer","enrolled_class")#联合索引
196         verbose_name_plural =  "06学员报名信息表"#verbose_name_plural给你的模型类起一个更可读的名字
197 
198 """07缴费记录表"""
199 class Payment(models.Model):
200     #ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
201     customer = models.ForeignKey("Customer",on_delete=models.CASCADE)#学员名字        关联到  客户信息表
202     course = models.ForeignKey("Course",verbose_name="所报课程",on_delete=models.CASCADE)#关联到  课程表
203 
204     #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称#默认值=500
205     amount = models.PositiveIntegerField(verbose_name="数额",default=500)#缴费数额
206 
207     #ForeignKey就是表与表之间的某种约定的关系#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
208     consultant = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#缴费给谁 关联到  账号表 #财务人员
209 
210     #DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
211     date=models.DateTimeField(auto_now_add=True)#创建时间(数据库自增)
212 
213     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
214         return "%s %s" %(self.customer,self.amount)#返回#格式化字符串#学员名字#缴费数额
215     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
216         verbose_name_plural = "07缴费记录表"#verbose_name_plural给你的模型类起一个更可读的名字
217 
218 """08每节课上课纪录表"""
219 class CourseRecord(models.Model):
220     # ForeignKey就是表与表之间的某种约定的关系#verbose_name是Admin中显示的字段名称 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
221     from_class = models.ForeignKey("ClassList",verbose_name="班级",on_delete=models.CASCADE) #那个班级
222 
223     #PositiveSmallIntegerField正小整数 0 ~ 32767 #verbose_name是Admin中显示的字段名称
224     day_num = models.PositiveSmallIntegerField(verbose_name="第几节(天)") #第几节课
225 
226     # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
227     teacher = models.ForeignKey("UserProfile",on_delete=models.CASCADE)#老师是谁    关联到    账号表
228 
229     #BooleanField布尔值类型#default=True默认(True)不允许出现空字符
230     has_homework = models.BooleanField(default=True) #有没有作业
231 
232     # CharField定长文本#名字最长128#Django可空#数据库可以为空
233     homework_title = models.CharField(max_length=128,blank=True,null=True) #作业标题
234 
235     #TextField无限制长度的文本#Django可空#数据库可以为空
236     homework_content = models.TextField(blank=True,null=True) #作业内容
237 
238     #TextField无限制长度的文本#verbose_name是Admin中显示的字段名称
239     outline =models.TextField(verbose_name="本节课程大纲") #课程主要讲什么
240 
241     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
242     date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
243 
244     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
245         return " %s:%s" %(self.from_class,self.day_num)#返回#格式化字符串#班级#第几节(天)
246     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
247         unique_together = ("from_class","day_num") #联合索引
248         verbose_name_plural = "08每节课上课纪录表" #verbose_name_plural给你的模型类起一个更可读的名字
249 
250 """09学习纪录"""
251 class StudyRecord(models.Model):
252     # ForeignKey就是表与表之间的某种约定的关系 #CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
253     student = models.ForeignKey("Enrollment",on_delete=models.CASCADE)#学生名字   关联到    学员报名信息表
254     course_record = models.ForeignKey("CourseRecord",on_delete=models.CASCADE)#开课记录   # 关联到    每节课上课纪录表
255 
256     attendance_choices = (# 本节课上课状态记录
257                             (0,"已签到"),
258                             (1,"迟到"),
259                             (2,"缺勤"),
260                             (3,"早退"),)
261     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
262     attendance = models.SmallIntegerField(choices=attendance_choices) # 本节课上课状态记录
263 
264     # ————————63PerfectCRM实现CRM讲师下载作业————————
265     delivery = models.BooleanField(default=False,verbose_name="交作业") #有没有交付作业
266     # ————————63PerfectCRM实现CRM讲师下载作业————————
267 
268 
269     # ————————61PerfectCRM实现CRM学生上传作业————————
270     homework_link = models.TextField(blank=True,null=True)#作业链接 #TextField无限制长度的文本#Django可空#数据库可以为空
271     # ————————61PerfectCRM实现CRM学生上传作业————————
272 
273     score_choices = (#学习成绩
274                      (100,"A+"),
275                      (90,"A"),
276                      (85,"B+"),
277                      (80,"B"),
278                      (75,"B-"),
279                      (70,"C+"),
280                      (65,"C"),
281                      (40,"C-"),
282                      (-20,"D"),
283                      (-50,"COPY"),
284                      (0,"N/A"),)
285     #PositiveSmallIntegerField正小整数 0 ~ 32767(省空间)#choices是Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
286     score = models.SmallIntegerField(choices=score_choices) #学习成绩
287 
288 
289     memo = models.TextField(blank=True,null=True)#TextField无限制长度的文本#Django可空#数据库可以为空
290 
291     # DateTimeField日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add创建时间(只读)
292     date = models.DateField(auto_now_add=True)#创建时间(数据库自增)
293 
294     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
295         return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#学生名字#开课记录#学习成绩
296     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
297         unique_together = ('student','course_record')#联合索引#学生名字#开课记录
298         verbose_name_plural =  "09学习纪录"#verbose_name_plural给你的模型类起一个更可读的名字
299 
300 # ————————34PerfectCRM实现CRM自定义用户————————
301 # """10账号表"""
302 # class UserProfile(models.Model):
303 #     from django.contrib.auth.models import User  # 使用django内置的用户表
304 #
305 #     #OneToOneField一对一  #User是django Admin里的账号表#CASCADE从父表删除或更新且自动删除或更新子表中匹配的行。
306 #     user = models.OneToOneField(User,on_delete=models.CASCADE)# 用户名 #创建外键,关联django用户表
307 #
308 #     name = models.CharField(max_length=32) #账号名(扩展用户字段)#CharField定长文本
309 #
310 #     #ManyToManyField多对多和外键工作方式相同,只不过我们处理的是QuerySet而不是模型实例。#Django可空
311 #     roles = models.ManyToManyField("Role",blank=True) #角色(权限)   # 双向一对多==多对多
312 #
313 #     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
314 #         return self.name #返回 #账号名
315 #     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
316 #         verbose_name_plural = "10账号表"#verbose_name_plural给你的模型类起一个更可读的名字
317 # ————————34PerfectCRM实现CRM自定义用户————————
318 
319 # ————————34PerfectCRM实现CRM自定义用户————————
320 #10账号表,创建用户和超级用户
321 from django.contrib.auth.models import BaseUserManager
322 class UserProfileManager(BaseUserManager):
323     def create_user(self, email, name, password=None):
324         """
325       创建并保存一个用户用给定的邮件,日期
326       出生和密码。
327         """
328         if not email:#没有email 报错
329             raise ValueError('用户必须有一个电子邮件地址')
330 
331         user = self.model(
332             email=self.normalize_email(email),#验证邮箱格式
333             name=name,
334         )
335         user.set_password(password)#加密
336         user.is_active = True
337         user.save(using=self._db)
338         return user
339     def create_superuser(self, email, name, password):
340         """
341       创建并保存一个超级用户具有给定邮件,日期
342       出生和密码。
343         """
344         user = self.create_user(email,
345             password=password,
346             name=name
347         )
348         user.is_active = True
349         user.is_superuser = True
350         user.save(using=self._db)
351         return user
352 
353 """10账号表"""
354 """
355 
356 #删除数据库
357 
358 #调用objects = UserProfileManager()#创建账号 #关联这个函数
359 
360 #运行 Terminal
361 #    生成 数据表
362 #    python manage.py makemigrations
363 #   数据表 迁移
364 #    python manage.py migrate
365 Django Admin里账号密码重置方法
366 #运行 Terminal  
367 python manage.py createsuperuser
368 
369 Email address:          admin@qq.com
370 用户名 :                 admin
371 Password:               admin123456
372 Password (again):       admin123456
373 """
374 from django.contrib.auth.models import AbstractBaseUser
375 # ————————35PerfectCRM实现CRM重写Admin密码修改————————
376 from django.utils.translation import ugettext_lazy as _  # 语言国际化
377 from django.utils.safestring import mark_safe
378 from django.contrib.auth.models import PermissionsMixin
379 # class UserProfile(AbstractBaseUser):
380 class UserProfile(AbstractBaseUser,PermissionsMixin):
381 # ————————35PerfectCRM实现CRM重写Admin密码修改————————
382     email=models.EmailField(
383         verbose_name='邮箱账号',
384         max_length=255,
385         unique=True#唯一  #登陆账号
386     )
387     name=models.CharField(max_length=32,verbose_name='用户名')
388 
389     # ————————35PerfectCRM实现CRM重写Admin密码修改————————
390     password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href="../password/">修改密码</a>'''))
391     # ————————35PerfectCRM实现CRM重写Admin密码修改————————
392 
393     is_active = models.BooleanField(default=True,verbose_name='合法账号')#权限#合法账号
394     is_superuser = models.BooleanField(default=False,verbose_name='超级账号') #超级账号
395     objects = UserProfileManager()#创建账号 #关联这个函数
396     USERNAME_FIELD ='email'#指定做为  #登陆账号
397     REQUIRED_FIELDS = ['name']#必填字段
398 
399 
400     # ————————60PerfectCRM实现CRM学生上课记录————————
401     stu_account = models.ForeignKey( "Customer", verbose_name='关联学员帐号', blank=True, null=True, on_delete=models.CASCADE,
402                                      help_text='报名成功后创建关联帐户' )
403     # ————————60PerfectCRM实现CRM学生上课记录————————
404 
405     def get_full_name(self):
406         return self.email
407     def get_short_name(self):
408         #用户确认的电子邮件地址
409         return self.email
410     def __str__(self):
411         return self.name
412     def has_perm(self,perm,obj=None):
413         #指明用户是否被认为活跃的。以反选代替删除帐号。
414         #最简单的可能的答案:是的,总是
415         return True   #有效 账号
416     def has_module_perms(self, app_label):
417         #指明用户是否可以登录到这个管理站点。
418         # 最简单的可能的答案:是的,总是
419         return True #职员状态
420     @property
421     def is_staff(self):
422         '''“用户的员工吗?”'''
423         #最简单的可能的答案:所有管理员都是员工
424         return self.is_superuser#是不是超级用户状态
425 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单   #settings.py
426 # ————————34PerfectCRM实现CRM自定义用户————————
427 
428 """11角色表"""
429 class Role(models.Model):
430     name = models.CharField(unique=True,max_length=32)#角色名#CharField定长文本#角色名不可以重复#最长度=32字节
431     def __str__(self):#__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
432         return self.name#返回 #角色名
433     class Meta: #通过一个内嵌类 "class Meta" 给你的 model 定义元数据
434         verbose_name_plural = "11角色表" #verbose_name_plural给你的模型类起一个更可读的名字
435 
436 """12标签表"""
437 class Tag(models.Model):
438     name =  models.CharField(max_length=64,unique=True) #标签名#CharField定长文本#最长度=64字节#不可以重复
439     def __str__(self): #__str__()是Python的一个“魔幻”方法,这个方法定义了当object调用str()时应该返回的值。
440         return self.name #返回 #标签名
441     class Meta:#通过一个内嵌类 "class Meta" 给你的 model 定义元数据
442         verbose_name_plural =  "12标签表" #verbose_name_plural给你的模型类起一个更可读的名字
443 
444 # ————————01PerfectCRM基本配置ADMIN————————
#models.py

 1 {#teacher_lesson_detail.html#}
 2 {## ————————63PerfectCRM实现CRM讲师下载作业————————#}
 3 {% extends 'bpm_master/bpm_sample.html' %}
 4 {% block right-container-content %} {#自定义内容开始 右边页面内容#}
 5     <div class="panel-default">
 6         <div class="panel-default">
 7             <div class="panel-body">
 8                 <h4>当前用户: {{ request.user }} | 讲师名字:{{ request.user.stu_account.name }} |
 9                     讲师QQ:{{ request.user.stu_account }} </h4>
10                 <ol class="breadcrumb">
11                     <li><a href="/bpm/teacher_class/">我的班级</a></li>
12                     <li><a href="{% url 'teacher_class_detail' classes_obj.id %}">{{ classes_obj }}</a></li>
13                     <li>
14                         <a href="{% url 'teacher_lesson_detail' classes_obj.id  courserecordlist.id %}">第{{ courserecordlist.day_num }}节</a>
15                     </li>
16                 </ol>
17                 <li>
18                     <a target="_blank"
19                        href="/king_admin/crm/courserecord/{{ courserecordlist.id }}/change/">作业标题:</a>
20                     <pre>{{ courserecordlist.homework_title }}</pre>
21                 </li>
22                 <li>
23                     <a target="_blank"
24                        href="/king_admin/crm/courserecord/{{ courserecordlist.id }}/change/">作业要求:</a>
25                     <pre>{{ courserecordlist.homework_content }}</pre>
26                 </li>
27 
28 
29                 <table class="table table-striped table-responsive">
30                     <thead>
31                     <tr>
32                         <th>学员ID</th>
33                         <th>学员姓名</th>
34                         <th>
35                             <a target="_blank" href="/king_admin/crm/studyrecord/?course_record={{ courserecord_id }} ">签到状态</a>
36                         </th>
37                         <th> 作业链接</th>
38                         <th>
39                             {% if courserecordlist.has_homework %}
40                                 <a href="{% url 'teacher_lesson_detail' classes_obj.id  courserecordlist.id %}">学员作业(多刷) </a>
41                             {% else %}
42                                 <a style="color: #ff1900" target="_blank"
43                                    href="/king_admin/crm/courserecord/{{ courserecordlist.id }}/change/">创建新作业</a>
44                             {% endif %}
45                         </th>
46                         <th>
47                             {% if courserecordlist.has_homework %}
48                                 <a href="{% url 'teacher_lesson_detail' classes_obj.id  courserecordlist.id %}">批改作业 </a>
49                             {% else %}
50                                 没有作业
51                             {% endif %}
52                         </th>
53                     </tr>
54                     </thead>
55 
56 
57                     <tbody>
58                     {% for studyrecrd in studyrecord_list %}
59                         <tr>
60                             <td>{{ studyrecrd.student.id }}</td>
61                             {#学员ID#}
62                             <td>{{ studyrecrd.student.customer.name }}</td>
63                             {#学员姓名#}
64                             <td>{{ studyrecrd.get_attendance_display }}</td>
65                             {#签到状态#}
66                             <td>
67                                 <pre style=" 240px;height: 60px">{{ studyrecrd.homework_link }}</pre>
68                             </td>
69                             {#作业链接#}
70                             <td>
71                                 {% if studyrecrd.delivery %}
72                                     <a href="{% url 'howk_down'  classes_obj.id studyrecrd.course_record_id studyrecrd.id %}">下载作业</a>
73                                 {% endif %}{#学员作业#}
74                             </td>
75                             <td>
76                                 {% if studyrecrd.course_record.has_homework %}
77                                     {% if studyrecrd.score == 0 %}
78                                         <a target="_blank"
79                                            href="/king_admin/crm/studyrecord/{{ studyrecrd.id }}/change/"
80                                            style="color: #ff1600">未批改</a>
81                                     {% else %}
82                                         <a target="_blank"
83                                            href="/king_admin/crm/studyrecord/{{ studyrecrd.id }}/change/"
84                                            style="color: #0014ff">{{ studyrecrd.get_score_display }}</a>
85                                     {% endif %}
86                                 {% endif %}{#批改作业#}
87                             </td>
88                         </tr>
89                     {% endfor %}
90                     </tbody>
91                 </table>
92             </div>
93         </div>
94     </div>
95 {% endblock %}
96 {## ————————63PerfectCRM实现CRM讲师下载作业————————#}
{#teacher_lesson_detail.html#}

 

 1 {#teacher_classes_detail.html#}
 2 {## ————————62PerfectCRM实现CRM讲师讲课记录————————#}
 3 {% extends 'bpm_master/bpm_sample.html' %}
 4 {% block right-container-content %} {#自定义内容开始 右边页面内容#}
 5     <div class="panel-default">
 6         <div class="panel-default">
 7             <div class="panel-body">
 8                 <h4>当前用户: {{ request.user }} | 讲师名字:{{ request.user.stu_account.name }} |
 9                     讲师QQ:{{ request.user.stu_account }} </h4>
10                 <ol class="breadcrumb">
11                     <li><a href="/bpm/teacher_class/">我的班级</a></li>
12                     <li><a href="{% url 'teacher_class_detail' classes_obj.id %}">{{ classes_obj }}</a></li>
13                 </ol>
14                 <table class="table table-striped table-responsive ">
15                     <thead>
16                     <tr>
17                         <th><a target="_blank" href="/king_admin/crm/courserecord/add/">课程节次</a></th>
18                         <th>签到状态</th>
19                         <th>本节作业</th>
20                         <th>上课日期</th>
21                         <th>本节大纲</th>
22                         <th>作业标题</th>
23                         <th>作业要求</th>
24                     </tr>
25                     </thead>
26 
27 
28                     <tbody>
29                     {% for courserecord in courserecordlist %}
30                         <tr>
31                             <td><a target="_blank"
32                                    href="/king_admin/crm/courserecord/{{ courserecord.id }}/change/">第 {{ courserecord.day_num }}节</a>
33                             </td>
34                             {#课程节次#}
35                             <td>
36                                 <a target="_blank"
37                                    href="/king_admin/crm/studyrecord/?course_record={{ courserecord.id }} ">点名/成绩</a>
38                             </td>
39                             {#签到状态#}
40                             <td>
41                                 {## ————————63PerfectCRM实现CRM讲师下载作业————————#}
42                                 <a href="{% url 'teacher_lesson_detail' class_id courserecord.id %}">
43                                    {## ————————63PerfectCRM实现CRM讲师下载作业————————#}
44                                 {{ courserecord.has_homework }}
45                                 </a>
46                             </td>
47                             {#本节作业#}
48                             <td> {{ courserecord.date }}</td>
49                             {#上课日期#}
50                             <td>
51                                 <pre style=" 240px;height: 60px">{{ courserecord.outline }} </pre>
52                             </td>
53                             {#本节大纲#}
54                             <td>
55                                 <pre style=" 240px;height: 60px">{{ courserecord.homework_title }}</pre>
56                             </td>
57                             {#作业标题#}
58                             <td>
59                                 <pre style=" 240px;height: 60px">{{ courserecord.homework_content }} </pre>
60                             </td>
61                             {#作业要求#}
62                         </tr>
63                     {% endfor %}
64                     </tbody>
65                 </table>
66             </div>
67         </div>
68     </div>
69 {% endblock %}
70 {## ————————62PerfectCRM实现CRM讲师讲课记录————————#}
{#teacher_classes_detail.html#}


 

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

原文地址:https://www.cnblogs.com/ujq3/p/9033154.html