Django項目:CRM(客戶關係管理系統)--71--61PerfectCRM實現CRM學生上傳做業

 

 1 # student_urls.py
 2 # ————————60PerfectCRM實現CRM學生上課記錄————————
 3 from django.conf.urls import url
 4 from bpm.student import student_views
 5 
 6 urlpatterns = [
 7     url(r'^student_course/$', student_views.student_course, name='student_course'),   #學生報名的課程
 8     url(r'^studyrecords/(\d+)/$', student_views.studyrecords, name='studyrecords'),  # #學生上課記錄列表StudyRecord
 9 
10     # ————————61PerfectCRM實現CRM學生上傳做業————————
11     url( r'^homework_detail/(\d+)/(\d+)/$', student_views.homework_detail, name='homework_detail' ),  # 做業詳情
12     # ————————61PerfectCRM實現CRM學生上傳做業————————
13 ]
14 # ————————60PerfectCRM實現CRM學生上課記錄————————
# student_urls.py

 

 

 

 

 1 # student_views.py
 2 # ————————60PerfectCRM實現CRM學生上課記錄————————
 3 from django.shortcuts import render #頁面返回
 4 from crm import models #數據庫
 5 from  django.contrib.auth.decorators import login_required # 登錄後頁面才能訪問
 6 #學生報名的課程
 7 @login_required # 登錄後頁面才能訪問
 8 def student_course(request):
 9     enrollmentlist=request.user.stu_account.enrollment_set.all()#根據帳號表關聯的ID獲取06學員報名信息表
10     return  render(request, 'bpm_student/student_course.html', locals())
11 
12 #學生上課記錄列表
13 @login_required # 登錄後頁面才能訪問
14 def studyrecords(request,enroll_obj_id):
15     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#根據ID獲取06學員報名信息表
16     studyrecordlist=enroll_obj.studyrecord_set.all()#根據06學員報名信息表的ID獲取09學習紀錄
17     return render(request,'bpm_student/studyrecords.html',locals())
18 
19 # ————————60PerfectCRM實現CRM學生上課記錄————————
20 
21 # ————————61PerfectCRM實現CRM學生上傳做業————————
22 from django.contrib.auth.decorators import login_required #登錄才能訪問
23 from PerfectCRM import settings #靜態配置文件  #做業上傳 # 上傳路徑
24 import os,json,time #系統操做
25 from django.shortcuts import HttpResponse #頁面返回
26 from django.shortcuts import redirect #頁面返回
27 #做業詳情
28 @login_required#登錄才能訪問
29 def homework_detail(request,enroll_obj_id,studyrecord_id):
30     studyrecord_obj=models.StudyRecord.objects.get(id=studyrecord_id)#取學習記錄 對象
31     enroll_obj=models.Enrollment.objects.get(id=enroll_obj_id)#取班級對象
32 
33     #               做業根目錄    班級ID      上課記錄ID               學習記錄ID
34     homework_path="{base_dir}/{class_id}/{course_record_id}/{studyercord_id}/".format(
35         base_dir=settings.HOMEWORK_DATA, #靜態配置文件
36         class_id=studyrecord_obj.student.enrolled_class_id,#09學習紀錄#學生名字#所報班級ID號
37         course_record_id=studyrecord_obj.course_record_id,#09學習紀錄#每節課上課紀錄表
38         studyercord_id=studyrecord_obj.id##09學習紀錄
39     )
40     print('homework_path路徑:',studyrecord_obj.student.enrolled_class_id,studyrecord_obj.course_record_id,studyrecord_obj.id)
41 
42     if os.path.exists(homework_path):#判斷目錄是否存在
43         file_lists = []  # 已經上傳的文件列表
44         for file_name in os.listdir( homework_path ):
45             f_path = '%s/%s' % (homework_path, file_name)  # 文件名字
46             modify_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.gmtime( os.stat( f_path ).st_mtime ) )  # 文件上傳時間
47             file_lists.append( [file_name, os.stat( f_path ).st_size, modify_time] )  # 添加到文件列表#文件名字#文件大小文件上傳時間
48 
49 
50     if request.method=="POST":#上傳
51         ret=False
52         data=request.POST.get('data') #ajax
53         if data:#若是有刪除動做
54             del_f_path="%s/%s"%(homework_path,data)#文件路徑
55             print('刪除文件,路徑:',del_f_path)
56             os.remove(del_f_path) #刪除
57             ret=True
58             return HttpResponse(json.dumps(ret))#ret=False
59         if request.is_ajax():  # ajax上傳圖片 #異步提交
60             print("POST",request.POST)
61             if not os.path.isdir( homework_path ):  # 沒有目錄 #isdir返回true,若是路徑名是指現有的目錄。
62                 os.makedirs( homework_path, exist_ok=True )  # 建立目錄  
63             for k,v in request.FILES.items():#上傳的文件
64                 with open('%s/%s'%(homework_path,v.name),'wb') as f:#chunk 寫入文件
65                     for chunk in v.chunks(): #循環寫文件
66                         f.write(chunk)
67             return HttpResponse( json.dumps( {"status": 0, 'mag': "上傳完成!", 'file_lists': file_lists} ) )  # 上傳文件返回
68 
69     if request.method=="POST":#上傳
70         link = request.POST.get( 'link' )  # 讓頁面POST提交的值,在頁面GET後仍然存在顯示
71         if link:
72             homework_link=models.StudyRecord.objects.filter( id=studyrecord_id ).update(homework_link=link)
73             return redirect('/bpm/homework_detail/%s/%s/' %(enroll_obj_id,studyrecord_id) )#跳轉到enrollment_rejection
74     return render(request,'bpm_student/homework_detail.html',locals())
75 # ————————61PerfectCRM實現CRM學生上傳做業————————
# student_views.py

 

 

 

  1 # settings.py
  2 
  3 """
  4 Django settings for PerfectCRM project.
  5 
  6 Generated by 'django-admin startproject' using Django 2.0.3.
  7 
  8 For more information on this file, see
  9 https://docs.djangoproject.com/en/2.0/topics/settings/
 10 
 11 For the full list of settings and their values, see
 12 https://docs.djangoproject.com/en/2.0/ref/settings/
 13 """
 14 
 15 import os
 16 
 17 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 18 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 19 
 20 
 21 # Quick-start development settings - unsuitable for production
 22 # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
 23 
 24 # SECURITY WARNING: keep the secret key used in production secret!
 25 SECRET_KEY = 'atkhzsd7emv4_okn@ynhji)p)qbpuvhq+a7@yx5=chaa0$l_br'
 26 
 27 # SECURITY WARNING: don't run with debug turned on in production!
 28 DEBUG = True
 29 
 30 ALLOWED_HOSTS = []
 31 
 32 
 33 # Application definition
 34 
 35 INSTALLED_APPS = [
 36     'django.contrib.admin',
 37     'django.contrib.auth',
 38     'django.contrib.contenttypes',
 39     'django.contrib.sessions',
 40     'django.contrib.messages',
 41     'django.contrib.staticfiles',
 42     
 43 # ————————04PerfectCRM實現King_admin註冊功能————————
 44     # 'crm.apps.CrmConfig',
 45     'crm',
 46 # ————————04PerfectCRM實現King_admin註冊功能————————
 47 
 48 # ————————02PerfectCRM建立ADMIN頁面————————
 49     'king_admin',
 50 # ————————02PerfectCRM建立ADMIN頁面————————
 51     # ————————38PerfectCRM實現全局帳號登陸註銷————————
 52     'gbacc',
 53     # ————————38PerfectCRM實現全局帳號登陸註銷————————
 54 
 55     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 56     'bpm',
 57     # ————————48PerfectCRM實現CRM客戶報名流程學生合同————————
 58 
 59 ]
 60 
 61 MIDDLEWARE = [
 62     'django.middleware.security.SecurityMiddleware',
 63     'django.contrib.sessions.middleware.SessionMiddleware',
 64     'django.middleware.common.CommonMiddleware',
 65     'django.middleware.csrf.CsrfViewMiddleware',
 66     'django.contrib.auth.middleware.AuthenticationMiddleware',
 67     'django.contrib.messages.middleware.MessageMiddleware',
 68     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 69 ]
 70 
 71 ROOT_URLCONF = 'PerfectCRM.urls'
 72 
 73 TEMPLATES = [
 74     {
 75         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 76 # ————————02PerfectCRM建立ADMIN頁面————————
 77         'DIRS': [os.path.join(BASE_DIR, 'templates'),
 78                   os.path.join(BASE_DIR, 'king_admin/king_templates'),
 79 
 80 # ————————03PerfectCRM建立基本數據————————
 81                   os.path.join(BASE_DIR, 'DBadd/DBadd_templates'),
 82 # ————————03PerfectCRM建立基本數據————————
 83                 # ————————38PerfectCRM實現全局帳號登陸註銷————————
 84                   os.path.join(BASE_DIR, 'gbacc/gbacc_templates'),
 85                 # ————————38PerfectCRM實現全局帳號登陸註銷————————
 86 
 87                 # ————————47PerfectCRM實現CRM客戶報名流程————————
 88                 os.path.join(BASE_DIR, 'bpm/bpm_templates'), ]
 89                 # ————————47PerfectCRM實現CRM客戶報名流程————————
 90 
 91 ,
 92 # ————————02PerfectCRM建立ADMIN頁面————————
 93         'APP_DIRS': True,
 94         'OPTIONS': {
 95             'context_processors': [
 96                 'django.template.context_processors.debug',
 97                 'django.template.context_processors.request',
 98                 'django.contrib.auth.context_processors.auth',
 99                 'django.contrib.messages.context_processors.messages',
100             ],
101         },
102     },
103 ]
104 
105 WSGI_APPLICATION = 'PerfectCRM.wsgi.application'
106 
107 
108 # Database
109 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
110 
111 DATABASES = {
112     'default': {
113         'ENGINE': 'django.db.backends.sqlite3',
114         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
115     }
116 }
117 
118 
119 # Password validation
120 # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
121 
122 AUTH_PASSWORD_VALIDATORS = [
123     {
124         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
125     },
126     {
127         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
128     },
129     {
130         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
131     },
132     {
133         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
134     },
135 ]
136 
137 
138 # Internationalization
139 # https://docs.djangoproject.com/en/2.0/topics/i18n/
140 
141 # ————————01PerfectCRM基本配置ADMIN————————
142 #LANGUAGE_CODE = 'en-us'
143 
144 #英文轉中文方法
145 LANGUAGE_CODE = 'zh-Hans'
146 # ————————01PerfectCRM基本配置ADMIN————————
147 
148 TIME_ZONE = 'UTC'
149 
150 USE_I18N = True
151 
152 USE_L10N = True
153 
154 USE_TZ = True
155 
156 
157 # Static files (CSS, JavaScript, Images)
158 # https://docs.djangoproject.com/en/2.0/howto/static-files/
159 
160 STATIC_URL = '/static/'
161 
162 # ————————01PerfectCRM基本配置ADMIN————————
163 STATICFILES_DIRS = [os.path.join(BASE_DIR,'king_admin/static'),
164 # ————————01PerfectCRM基本配置ADMIN————————
165                     # ————————38PerfectCRM實現全局帳號登陸註銷————————
166                     os.path.join(BASE_DIR, 'gbacc/static'),
167                     # ————————38PerfectCRM實現全局帳號登陸註銷————————
168                     
169                     # ————————47PerfectCRM實現CRM客戶報名流程————————
170                     os.path.join(BASE_DIR, 'bpm/static'),]
171                     # ————————47PerfectCRM實現CRM客戶報名流程————————
172 
173 
174 # ————————34PerfectCRM實現CRM自定義用戶————————
175 AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表單
176 # ————————34PerfectCRM實現CRM自定義用戶————————
177 
178 
179 
180 # ————————44PerfectCRM實現帳號快速註冊登錄————————
181 # send e-mail
182 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  #email後端
183 EMAIL_USE_TLS = False   #是否使用TLS安全傳輸協議
184 EMAIL_USE_SSL = True    #是否使用SSL加密,qq企業郵箱要求使用
185 EMAIL_HOST = 'smtp.sina.cn'   #發送郵件的郵箱 的 SMTP服務器       #根據狀況從新配置
186 EMAIL_PORT = 465                 #發件箱的SMTP服務器端口 #通常不須要修改465
187 EMAIL_HOST_USER = 'perfectcrm@sina.cn'    #發送郵件的郵箱帳號     #根據狀況從新配置  #perfectcrm@sina.cn   pydjango@sina.cn
188 EMAIL_HOST_PASSWORD = 'admin123456'         #發送郵件的郵箱密碼    #根據狀況從新配置
189 
190 # ————————44PerfectCRM實現帳號快速註冊登錄————————
191 
192 
193 # ————————46PerfectCRM實現登錄後頁面才能訪問————————
194 LOGIN_URL = '/gbacc/gbacc_login/'# login_url 配置      #默認 /accounts/login/  #注意: / (絕對路徑)
195 # ————————46PerfectCRM實現登錄後頁面才能訪問————————
196 
197 # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
198 ENROLLED_DATA='%s/bpm/static/enrolled_data'%BASE_DIR#證件上傳 # 上傳路徑
199 # ————————51PerfectCRM實現CRM客戶報名流程學生合同上傳照片————————
200 
201 
202 # ————————61PerfectCRM實現CRM學生上傳做業————————
203 HOMEWORK_DATA='%s/bpm/static/homeworks'%BASE_DIR  #做業上傳 # 上傳路徑
204 # ————————61PerfectCRM實現CRM學生上傳做業————————
# settings.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     # ————————61PerfectCRM實現CRM學生上傳做業————————
265     homework_link = models.TextField(blank=True,null=True)#做業連接 #TextField無限制長度的文本#Django可空#數據庫能夠爲空
266     # ————————61PerfectCRM實現CRM學生上傳做業————————
267 
268     score_choices = (#學習成績
269                      (100,"A+"),
270                      (90,"A"),
271                      (85,"B+"),
272                      (80,"B"),
273                      (75,"B-"),
274                      (70,"C+"),
275                      (65,"C"),
276                      (40,"C-"),
277                      (-20,"D"),
278                      (-50,"COPY"),
279                      (0,"N/A"),)
280     #PositiveSmallIntegerField正小整數 0 ~ 32767(省空間)#choices是Admin中顯示選擇框的內容,用不變更的數據放在內存中從而避免跨表操做
281     score = models.SmallIntegerField(choices=score_choices) #學習成績
282 
283 
284     memo = models.TextField(blank=True,null=True)#TextField無限制長度的文本#Django可空#數據庫能夠爲空
285 
286     # DateTimeField日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] #auto_now_add建立時間(只讀)
287     date = models.DateField(auto_now_add=True)#建立時間(數據庫自增)
288 
289     def __str__(self):#__str__()是Python的一個「魔幻」方法,這個方法定義了當object調用str()時應該返回的值。
290         return "%s %s %s" % (self.student, self.course_record, self.score)#返回#格式化字符串#學生名字#開課記錄#學習成績
291     class Meta:#經過一個內嵌類 "class Meta" 給你的 model 定義元數據
292         unique_together = ('student','course_record')#聯合索引#學生名字#開課記錄
293         verbose_name_plural =  "09學習紀錄"#verbose_name_plural給你的模型類起一個更可讀的名字
294 
295 # ————————34PerfectCRM實現CRM自定義用戶————————
296 # """10帳號表"""
297 # class UserProfile(models.Model):
298 #     from django.contrib.auth.models import User  # 使用django內置的用戶表
299 #
300 #     #OneToOneField一對一  #User是django Admin裏的帳號表#CASCADE從父表刪除或更新且自動刪除或更新子表中匹配的行。
301 #     user = models.OneToOneField(User,on_delete=models.CASCADE)# 用戶名 #建立外鍵,關聯django用戶表
302 #
303 #     name = models.CharField(max_length=32) #帳號名(擴展用戶字段)#CharField定長文本
304 #
305 #     #ManyToManyField多對多和外鍵工做方式相同,只不過咱們處理的是QuerySet而不是模型實例。#Django可空
306 #     roles = models.ManyToManyField("Role",blank=True) #角色(權限)   # 雙向一對多==多對多
307 #
308 #     def __str__(self):#__str__()是Python的一個「魔幻」方法,這個方法定義了當object調用str()時應該返回的值。
309 #         return self.name #返回 #帳號名
310 #     class Meta: #經過一個內嵌類 "class Meta" 給你的 model 定義元數據
311 #         verbose_name_plural = "10帳號表"#verbose_name_plural給你的模型類起一個更可讀的名字
312 # ————————34PerfectCRM實現CRM自定義用戶————————
313 
314 # ————————34PerfectCRM實現CRM自定義用戶————————
315 #10帳號表,建立用戶和超級用戶
316 from django.contrib.auth.models import BaseUserManager
317 class UserProfileManager(BaseUserManager):
318     def create_user(self, email, name, password=None):
319         """
320       建立並保存一個用戶用給定的郵件,日期
321       出生和密碼。
322         """
323         if not email:#沒有email 報錯
324             raise ValueError('用戶必須有一個電子郵件地址')
325 
326         user = self.model(
327             email=self.normalize_email(email),#驗證郵箱格式
328             name=name,
329         )
330         user.set_password(password)#加密
331         user.is_active = True
332         user.save(using=self._db)
333         return user
334     def create_superuser(self, email, name, password):
335         """
336       建立並保存一個超級用戶具備給定郵件,日期
337       出生和密碼。
338         """
339         user = self.create_user(email,
340             password=password,
341             name=name
342         )
343         user.is_active = True
344         user.is_superuser = True
345         user.save(using=self._db)
346         return user
347 
348 """10帳號表"""
349 """
350 
351 #刪除數據庫
352 
353 #調用objects = UserProfileManager()#建立帳號 #關聯這個函數
354 
355 #運行 Terminal
356 #    生成 數據表
357 #    python manage.py makemigrations
358 #   數據表 遷移
359 #    python manage.py migrate
360 Django Admin裏帳號密碼重置方法
361 #運行 Terminal  
362 python manage.py createsuperuser
363 
364 Email address:          admin@qq.com
365 用戶名 :                 admin
366 Password:               admin123456
367 Password (again):       admin123456
368 """
369 from django.contrib.auth.models import AbstractBaseUser
370 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
371 from django.utils.translation import ugettext_lazy as _  # 語言國際化
372 from django.utils.safestring import mark_safe
373 from django.contrib.auth.models import PermissionsMixin
374 # class UserProfile(AbstractBaseUser):
375 class UserProfile(AbstractBaseUser,PermissionsMixin):
376 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
377     email=models.EmailField(
378         verbose_name='郵箱帳號',
379         max_length=255,
380         unique=True#惟一  #登錄帳號
381     )
382     name=models.CharField(max_length=32,verbose_name='用戶名')
383 
384     # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
385     password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密碼</a>'''))
386     # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
387 
388     is_active = models.BooleanField(default=True,verbose_name='合法帳號')#權限#合法帳號
389     is_superuser = models.BooleanField(default=False,verbose_name='超級帳號') #超級帳號
390     objects = UserProfileManager()#建立帳號 #關聯這個函數
391     USERNAME_FIELD ='email'#指定作爲  #登錄帳號
392     REQUIRED_FIELDS = ['name']#必填字段
393 
394 
395     # ————————60PerfectCRM實現CRM學生上課記錄————————
396     stu_account = models.ForeignKey( "Customer", verbose_name='關聯學員賬號', blank=True, null=True, on_delete=models.CASCADE,
397                                      help_text='報名成功後建立關聯賬戶' )
398     # ————————60PerfectCRM實現CRM學生上課記錄————————
399 
400     def get_full_name(self):
401         return self.email
402     def get_short_name(self):
403         #用戶確認的電子郵件地址
404         return self.email
405     def __str__(self):
406         return self.name
407     def has_perm(self,perm,obj=None):
408         #指明用戶是否被認爲活躍的。以反選代替刪除賬號。
409         #最簡單的可能的答案:是的,老是
410         return True   #有效 帳號
411     def has_module_perms(self, app_label):
412         #指明用戶是否能夠登陸到這個管理站點。
413         # 最簡單的可能的答案:是的,老是
414         return True #職員狀態
415     @property
416     def is_staff(self):
417         '''「用戶的員工嗎?」'''
418         #最簡單的可能的答案:全部管理員都是員工
419         return self.is_superuser#是否是超級用戶狀態
420 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表單   #settings.py
421 # ————————34PerfectCRM實現CRM自定義用戶————————
422 
423 """11角色表"""
424 class Role(models.Model):
425     name = models.CharField(unique=True,max_length=32)#角色名#CharField定長文本#角色名不能夠重複#最長度=32字節
426     def __str__(self):#__str__()是Python的一個「魔幻」方法,這個方法定義了當object調用str()時應該返回的值。
427         return self.name#返回 #角色名
428     class Meta: #經過一個內嵌類 "class Meta" 給你的 model 定義元數據
429         verbose_name_plural = "11角色表" #verbose_name_plural給你的模型類起一個更可讀的名字
430 
431 """12標籤表"""
432 class Tag(models.Model):
433     name =  models.CharField(max_length=64,unique=True) #標籤名#CharField定長文本#最長度=64字節#不能夠重複
434     def __str__(self): #__str__()是Python的一個「魔幻」方法,這個方法定義了當object調用str()時應該返回的值。
435         return self.name #返回 #標籤名
436     class Meta:#經過一個內嵌類 "class Meta" 給你的 model 定義元數據
437         verbose_name_plural =  "12標籤表" #verbose_name_plural給你的模型類起一個更可讀的名字
438 
439 # ————————01PerfectCRM基本配置ADMIN————————
#models.py

 

 

 

 

 

 

 

  1 {#homework_detail.html#}
  2 {## ————————61PerfectCRM實現CRM學生上傳做業————————#}
  3 {% extends 'bpm_master/bpm_sample.html' %}
  4 {% block right-container-content %} {#自定義內容開始 右邊頁面內容#}
  5     <div class="panel-default">
  6         <div class="panel-body">
  7             <h4>當前用戶: {{ request.user }} | 學員名字:{{ request.user.stu_account.name }} |
  8                 學員QQ:{{ request.user.stu_account }}</h4>
  9             <div class="row" style="margin-bottom: 20px">
 10                 <ol class="breadcrumb">
 11                     <li><a href="/bpm/my_course/">個人課程</a></li>
 12                     <li><a href="/bpm/studyrecords/{{ enroll_obj.id }}/">{{ enroll_obj.enrolled_class }}</a></li>
 13                     <li><a href="#">第:{{ studyrecord_obj.course_record.day_num }}節</a></li>
 14                 </ol>
 15             </div>
 16             <h4>做業標題:{{ studyrecord_obj.course_record.homework_title }}</h4>
 17             <h4>做業詳情:
 18                 <pre>{{ studyrecord_obj.course_record.homework_content }}</pre>
 19             </h4>
 20             <h4>老師評語:
 21                 <pre>{{ studyrecord_obj.memo }}</pre>
 22             </h4>
 23             <h4>本節成績: {{ studyrecord_obj.score }} </h4>
 24             <h4>本節做業連接:
 25                 <pre>{{ studyrecord_obj.homework_link }}</pre>
 26             </h4>
 27             <form method="post" class="form-horizontal" role="form">{% csrf_token %}
 28                 <input type="text" class="form-control" name="link" placeholder="做業連接">
 29                 <input type="submit" class="btn btn-info" value="提交">
 30             </form>
 31 
 32 
 33             <hr>
 34             <h4>已經上傳的文件: <a id="refresh">刷新</a></h4>
 35             <div class="row">
 36                 <div class="col-xs-9 col-md-6">
 37                     {% for file in file_lists %}
 38                         <div class="right">
 39                             {% for foo in file %}
 40                                 <a>{{ foo }}</a>  |
 41                             {% endfor %}
 42                             <span class="img_f hide">{{ file.0 }}</span>
 43                             <a class="del_img">刪除</a>
 44                         </div>
 45                         <br>
 46                     {% endfor %}
 47                 </div>
 48             </div>
 49             <h4>請上傳做業</h4>
 50             <form action="{{ request.path }}" method="post" id="dropz" enctype="multipart/form-data"
 51                   class="form-group dropzone">{% csrf_token %}
 52                 <input type="hidden" name="file_id" ng-model="file_id" id="file_id"/>
 53             </form>
 54             <h4>課程大綱:
 55                 <pre>{{ studyrecord_obj.course_record.outline }}</pre>
 56             </h4>
 57         </div>
 58     </div>
 59 {% endblock %}
 60 
 61 
 62 {% block js %}
 63     <script>
 64         //頁面加載時綁定按鈕點擊事件
 65         $("#refresh").click(function () {
 66             window.location.reload();//刷新當前頁面.
 67         });
 68 
 69         $('.del_img').click(function () {
 70             s = $(this);
 71             texts = s.parent().children("span").text();
 72             {#        alert(texts);#}
 73             $.ajax({
 74                 url: "{{ requset.path }}",
 75                 type: "post",
 76                 data: {"data": texts},
 77                 headers: {'X-CSRFtoken': $.cookie('csrftoken')},
 78                 success: function (arg) {
 79                     if (arg) {
 80                         alert('刪除成功!');
 81                         s.parent('div').addClass('hide');
 82                         {#  #添加樣式#隱藏#}
 83                     }
 84                 }
 85             })
 86         });
 87 
 88 
 89         Dropzone.autoDiscover = false;
 90         appElement = document.querySelector('div .inmodal');
 91         myDropzone = new Dropzone("#dropz", {
 92             url: "{{ request.path }}",//文件提交地址
 93             paramName: "file", //默認爲file
 94             method: "post",  //也可用put
 95             addRemoveLinks: true,
 96             maxFiles: 1,//一次性上傳的文件數量上限
 97             maxFilesize: 2, //文件大小,單位:MB
 98             acceptedFiles: ".zip,.7z", //上傳的類型
 99             {#            uploadMultiple: true,#}//上傳多個
100             parallelUploads: 1,//一次上傳的文件數量
101             dictDefaultMessage: '請將做業壓縮打包後上傳',
102             dictMaxFilesExceeded: "您最多隻能上傳1個文件!",
103             dictResponseError: '文件上傳失敗!',
104             dictInvalidFileType: "文件類型只能是*.zip,*.7z。",
105             dictFallbackMessage: "瀏覽器不受支持",
106             dictFileTooBig: "文件過大上傳文件最大支持.",
107             dictRemoveLinks: "刪除",
108             dictCancelUpload: "取消",
109 
110 
111             init: function () {
112                 this.on("addedfile", function (file) {
113                     //上傳文件時觸發的事件
114                     document.querySelector('div .dz-default').style.display = 'none';
115                 });
116                 this.on("success", function (file, data) {
117                     //上傳成功觸發的事件
118                     console.log('ok');
119                 });
120                 this.on("error", function (file, data) {
121                     //上傳失敗觸發的事件
122                     console.log('fail');
123                     var message = '';
124                     //lavarel框架有一個表單驗證,
125                     //對於ajax請求,JSON 響應會發送一個 422 HTTP 狀態碼,
126                     //對應file.accepted的值是false,在這裏捕捉表單驗證的錯誤提示
127                     if (file.accepted) {
128                         $.each(data, function (key, val) {
129                             message = message + val[0] + ';';
130                         });
131                         //控制器層面的錯誤提示,file.accepted = true的時候;
132                         alert(message);
133                     }
134                 });
135                 this.on("removedfile", function (file) {
136                     //刪除文件時觸發的方法
137                     document.querySelector('div .dz-default').style.display = 'block';
138                 });
139             }
140         });
141     </script>
142 {% endblock %}
143 {## ————————61PerfectCRM實現CRM學生上傳做業————————#}
{#homework_detail.html#}

 

 

 

 1 {#studyrecords.html#}
 2 {## ————————60PerfectCRM實現CRM學生上課記錄————————#}
 3 {% extends 'bpm_master/bpm_sample.html' %}
 4 {% load bpm_tags %}
 5 {% block right-container-content %} {#自定義內容開始 右邊頁面內容#}
 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/student_course/">個人課程</a></li>
12                 <li><a href="/bpm/studyrecords/{{ enroll_obj.id }}/">{{ enroll_obj.enrolled_class }}</a></li>
13             </ol>
14 
15             <table class="table table-striped table-responsive ">
16                 <thead>
17                 <tr>
18                     <th>課程節次</th>
19                     <th>簽到狀態</th>
20                     <th>本節做業</th>
21                     <th>本節成績</th>
22                     <th>本節講師</th>
23                     <th>上課日期</th>
24                     <th>本節大綱</th>
25                     <th>做業標題</th>
26                     <th>做業要求</th>
27                 </tr>
28                 </thead>
29 
30 
31                 <tbody>
32                 {% for studyrecord in studyrecordlist %}
33                     <tr>
34                         <td>{{ studyrecord.course_record.day_num }}</td>
35                         {#課程節次#}
36                         <td>{{ studyrecord.get_attendance_display }}</td>
37                         {#簽到狀態#}
38                         <td>
39                             <a href="{% url 'homework_detail' enroll_obj.id studyrecord.id %}">
40                                 {{ studyrecord.course_record.has_homework }}
41                             </a>
42                         </td>
43                         {#本節做業#}
44                         <td>{{ studyrecord.get_score_display }}</td>
45                         {#本節成績#}
46                         <td>{{ studyrecord.course_record.teacher }}</td>
47                         {#本節講師#}
48                         <td>{{ studyrecord.course_record.date }}</td>
49                         {#上課日期#}
50                         <td>
51                             <pre style="width: 240px;height: 60px">{{ studyrecord.course_record.outline }}</pre>
52                             {#本節大綱#}
53                         </td>
54                         <td>
55                             <pre style="width: 240px;height: 60px">{{ studyrecord.course_record.homework_title }}</pre>
56                             {#做業標題#}
57                         </td>
58                         <td>
59                             <pre style="width: 240px;height: 60px">{{ studyrecord.course_record.homework_content }}</pre>
60                             {#做業要求#}
61                         </td>
62                     </tr>
63                 {% endfor %}
64                 </tbody>
65             </table>
66         </div>
67     </div>
68 {% endblock %}
69 {## ————————60PerfectCRM實現CRM學生上課記錄————————#}
{#studyrecords.html#}

 

 

 

 

 

 

 

 

 

 


 

若是感受本章博客對您有幫助,請盡情打賞吧!

相關文章
相關標籤/搜索