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
390 # ————————72PerfectCRM實現CRM動態菜單和角色————————
391 branch = models.ForeignKey( "Branch", verbose_name="所屬校區", blank=True, null=True, on_delete=models.CASCADE )
392 roles = models.ManyToManyField( 'Role', verbose_name="角色", blank=True )
393 memo = models.TextField( blank=True, null=True, default=None, verbose_name="備注" )
394 from django.utils import timezone
395 date_joined = models.DateTimeField( verbose_name="創建時間", default=timezone.now )
396 # ————————72PerfectCRM實現CRM動態菜單和角色————————
397
398 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
399 password = models.CharField(_('password'), max_length=128, help_text=mark_safe('''<a href=\"../password/\">修改密碼</a>'''))
400 # ————————35PerfectCRM實現CRM重寫Admin密碼修改————————
401
402 is_active = models.BooleanField(default=True,verbose_name='合法賬號')#權限#合法賬號
403 is_superuser = models.BooleanField(default=False,verbose_name='超級賬號') #超級賬號
404 objects = UserProfileManager()#創建賬號 #關聯這個函數
405 USERNAME_FIELD ='email'#指定做為 #登陸賬號
406 REQUIRED_FIELDS = ['name']#必填字段
407
408
409 # ————————60PerfectCRM實現CRM學生上課記錄————————
410 stu_account = models.ForeignKey( "Customer", verbose_name='關聯學員帳號', blank=True, null=True, on_delete=models.CASCADE,
411 help_text='報名成功后創建關聯帳戶' )
412 # ————————60PerfectCRM實現CRM學生上課記錄————————
413
414 def get_full_name(self):
415 return self.email
416 def get_short_name(self):
417 #用戶確認的電子郵件地址
418 return self.email
419 def __str__(self):
420 return self.name
421 def has_perm(self,perm,obj=None):
422 #指明用戶是否被認為活躍的。以反選代替刪除帳號。
423 #最簡單的可能的答案:是的,總是
424 return True #有效 賬號
425 def has_module_perms(self, app_label):
426 #指明用戶是否可以登錄到這個管理站點。
427 # 最簡單的可能的答案:是的,總是
428 return True #職員狀態
429 @property
430 def is_staff(self):
431 '''“用戶的員工嗎?”'''
432 #最簡單的可能的答案:所有管理員都是員工
433 return self.is_superuser#是不是超級用戶狀態
434 # AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表單 #settings.py
435 # ————————34PerfectCRM實現CRM自定義用戶————————
436 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
437 class Meta:
438 verbose_name_plural = '10CRM賬戶表'
439 permissions = (
440 ('crm_010101_all_table_data_list_GET', '010101_全部查看數據_GET'),
441 ('crm_010102_all_table_data_list_POST', '010102_全部查看數據_POST'),
442 ('crm_010103_all_table_add_GET', '010103_全部添加數據_GET'),
443 ('crm_010104_all_table_add_POST', '010104_全部添加數據_POST'),
444 ('crm_010105_all_table_change_GET', '010105_全部修改數據_GET'),
445 ('crm_010106_all_table_change_POST', '010106_全部修改數據_POST'),
446 ('crm_010107_all_table_delete_GET', '010107_全部刪除數據_GET'),
447 ('crm_010108_all_table_delete_POST', '010108_全部刪除數據_POST'),
448 ('crm_010109_all_password_reset_GET', '010109_全部密碼重置_GET'),
449 ('crm_010110_all_password_reset_POST', '010110_全部密碼重置_POST'),
450
451 ('crm_010201_only_view_Branch_GET', '010201_只能查看校區表_GET'),
452 ('crm_010202_only_view_Branch_POST', '010202_只能查看校區表_POST'),
453 ('crm_010203_only_add_Branch_GET', '010203_只能添加校區表_GET'),
454 ('crm_010204_only_add_Branch_POST', '010204_只能添加校區表_POST'),
455 ('crm_010205_only_change_Branch_GET', '010205_只能修改校區表_GET'),
456 ('crm_010206_only_change_Branch_POST', '010206_只能修改校區表_POST'),
457 ('crm_010207_only_delete_Branch_GET', '010207_只能刪除校區表_GET'),
458 ('crm_010208_only_delete_Branch_POST', '010208_只能刪除校區表_POST'),
459
460 ('crm_010301_only_view_ClassList_GET', '010301_只能查看班級表_GET'),
461 ('crm_010302_only_view_ClassList_POST', '010302_只能查看班級表_POST'),
462 ('crm_010303_only_add_ClassList_GET', '010303_只能添加班級表_GET'),
463 ('crm_010304_only_add_ClassList_POST', '010304_只能添加班級表_POST'),
464 ('crm_010305_only_change_ClassList_GET', '010305_只能修改班級表_GET'),
465 ('crm_010306_only_change_ClassList_POST', '010306_只能修改班級表_POST'),
466 ('crm_010307_only_delete_ClassList_GET', '010307_只能刪除班級表_GET'),
467 ('crm_010308_only_delete_ClassList_POST', '010308_只能刪除班級表_POST'),
468
469 ('crm_010401_only_view_Course_GET', '010401_只能查看課程表_GET'),
470 ('crm_010402_only_view_Course_POST', '010402_只能查看課程表_POST'),
471 ('crm_010403_only_add_Course_GET', '010403_只能添加課程表_GET'),
472 ('crm_010404_only_add_Course_POST', '010404_只能添加課程表_POST'),
473 ('crm_010405_only_change_Course_GET', '010405_只能修改課程表_GET'),
474 ('crm_010406_only_change_Course_POST', '010406_只能修改課程表_POST'),
475 ('crm_010407_only_delete_Course_GET', '010407_只能刪除課程表_GET'),
476 ('crm_010408_only_delete_Course_POST', '010408_只能刪除課程表_POST'),
477
478 ('crm_010501_only_view_Customer_GET', '010501_只能查看客戶表_GET'),
479 ('crm_010502_only_view_Customer_POST', '010502_只能查看客戶表_POST'),
480 ('crm_010503_only_add_Customer_GET', '010503_只能添加客戶表_GET'),
481 ('crm_010504_only_add_Customer_POST', '010504_只能添加客戶表_POST'),
482 ('crm_010505_only_change_Customer_GET', '010505_只能修改客戶表_GET'),
483 ('crm_010506_only_change_Customer_POST', '010506_只能修改客戶表_POST'),
484 ('crm_010507_only_delete_Customer_GET', '010507_只能刪除客戶表_GET'),
485 ('crm_010508_only_delete_Customer_POST', '010508_只能刪除客戶表_POST'),
486
487 ('crm_010601_only_view_CustomerFollowUp_GET', '010601_只能查看跟進表_GET'),
488 ('crm_010602_only_view_CustomerFollowUp_POST', '010602_只能查看跟進表_POST'),
489 ('crm_010603_only_add_CustomerFollowUp_GET', '010603_只能添加跟進表_GET'),
490 ('crm_010604_only_add_CustomerFollowUp_POST', '010604_只能添加跟進表_POST'),
491 ('crm_010605_only_change_CustomerFollowUp_GET', '010605_只能修改跟進表_GET'),
492 ('crm_010606_only_change_CustomerFollowUp_POST', '010606_只能修改跟進表_POST'),
493 ('crm_010607_only_delete_CustomerFollowUp_GET', '010607_只能刪除跟進表_GET'),
494 ('crm_010608_only_delete_CustomerFollowUp_POST', '010608_只能刪除跟進表_POST'),
495
496 ('crm_010701_only_view_Enrollment_GET', '010701_只能查看報名表_GET'),
497 ('crm_010702_only_view_Enrollment_POST', '010702_只能查看報名表_POST'),
498 ('crm_010703_only_add_Enrollment_GET', '010703_只能添加報名表_GET'),
499 ('crm_010704_only_add_Enrollment_POST', '010704_只能添加報名表_POST'),
500 ('crm_010705_only_change_Enrollment_GET', '010705_只能修改報名表_GET'),
501 ('crm_010706_only_change_Enrollment_POST', '010706_只能修改報名表_POST'),
502 ('crm_010707_only_delete_Enrollment_GET', '010707_只能刪除報名表_GET'),
503 ('crm_010708_only_delete_Enrollment_POST', '010708_只能刪除報名表_POST'),
504
505 ('crm_010801_only_view_Payment_GET', '010801_只能查看繳費表_GET'),
506 ('crm_010802_only_view_Payment_POST', '010802_只能查看繳費表_POST'),
507 ('crm_010803_only_add_Payment_GET', '010803_只能添加繳費表_GET'),
508 ('crm_010804_only_add_Payment_POST', '010804_只能添加繳費表_POST'),
509 ('crm_010805_only_change_Payment_GET', '010805_只能修改繳費表_GET'),
510 ('crm_010806_only_change_Payment_POST', '010806_只能修改繳費表_POST'),
511 ('crm_010807_only_delete_Payment_GET', '010807_只能刪除繳費表_GET'),
512 ('crm_010808_only_delete_Payment_POST', '010808_只能刪除繳費表_POST'),
513
514 ('crm_010901_only_view_CourseRecord_GET', '010901_只能查看上課表_GET'),
515 ('crm_010902_only_view_CourseRecord_POST', '010902_只能查看上課表_POST'),
516 ('crm_010903_only_add_CourseRecord_GET', '010903_只能添加上課表_GET'),
517 ('crm_010904_only_add_CourseRecord_POST', '010904_只能添加上課表_POST'),
518 ('crm_010905_only_change_CourseRecord_GET', '010905_只能修改上課表_GET'),
519 ('crm_010906_only_change_CourseRecord_POST', '010906_只能修改上課表_POST'),
520 ('crm_010907_only_delete_CourseRecord_GET', '010907_只能刪除上課表_GET'),
521 ('crm_010908_only_delete_CourseRecord_POST', '010908_只能刪除上課表_POST'),
522
523 ('crm_011001_only_view_StudyRecord_GET', '011001_只能查看學習表_GET'),
524 ('crm_011002_only_view_StudyRecord_POST', '011002_只能查看學習表_POST'),
525 ('crm_011003_only_add_StudyRecord_GET', '011003_只能添加學習表_GET'),
526 ('crm_011004_only_add_StudyRecord_POST', '011004_只能添加學習表_POST'),
527 ('crm_011005_only_change_StudyRecord_GET', '011005_只能修改學習表_GET'),
528 ('crm_011006_only_change_StudyRecord_POST', '011006_只能修改學習表_POST'),
529 ('crm_011007_only_delete_StudyRecord_GET', '011007_只能刪除學習表_GET'),
530 ('crm_011008_only_delete_StudyRecord_POST', '011008_只能刪除學習表_POST'),
531
532 ('crm_011101_only_view_UserProfile_GET', '011101_只能查看賬號表_GET'),
533 ('crm_011102_only_view_UserProfile_POST', '011102_只能查看賬號表_POST'),
534 ('crm_011103_only_add_UserProfile_GET', '011103_只能添加賬號表_GET'),
535 ('crm_011104_only_add_UserProfile_POST', '011104_只能添加賬號表_POST'),
536 ('crm_011105_only_change_UserProfile_GET', '011105_只能修改賬號表_GET'),
537 ('crm_011106_only_change_UserProfile_POST', '011106_只能修改賬號表_POST'),
538 ('crm_011107_only_delete_UserProfile_GET', '011107_只能刪除賬號表_GET'),
539 ('crm_011108_only_delete_UserProfile_POST', '011108_只能刪除賬號表_POST'),
540
541 ('crm_011201_only_view_Role_GET', '011201_只能查看角色表_GET'),
542 ('crm_011202_only_view_Role_POST', '011202_只能查看角色表_POST'),
543 ('crm_011203_only_add_Role_GET', '011203_只能添加角色表_GET'),
544 ('crm_011204_only_add_Role_POST', '011204_只能添加角色表_POST'),
545 ('crm_011205_only_change_Role_GET', '011205_只能修改角色表_GET'),
546 ('crm_011206_only_change_Role_POST', '011206_只能修改角色表_POST'),
547 ('crm_011207_only_delete_Role_GET', '011207_只能刪除角色表_GET'),
548 ('crm_011208_only_delete_Role_POST', '011208_只能刪除角色表_POST'),
549
550 ('crm_011301_only_view_Tag_GET', '011301_只能查看標簽表_GET'),
551 ('crm_011302_only_view_Tag_POST', '011302_只能查看標簽表_POST'),
552 ('crm_011303_only_add_Tag_GET', '011303_只能添加標簽表_GET'),
553 ('crm_011304_only_add_Tag_POST', '011304_只能添加標簽表_POST'),
554 ('crm_011305_only_change_Tag_GET', '011305_只能修改標簽表_GET'),
555 ('crm_011306_only_change_Tag_POST', '011306_只能修改標簽表_POST'),
556 ('crm_011307_only_delete_Tag_GET', '011307_只能刪除標簽表_GET'),
557 ('crm_011308_only_delete_Tag_POST', '011308_只能刪除標簽表_POST'),
558
559 ('crm_011401_only_view_FirstLayerMenu_GET', '011401_只能查看一層菜單_GET'),
560 ('crm_011402_only_view_FirstLayerMenu_POST', '011402_只能查看一層菜單_POST'),
561 ('crm_011403_only_add_FirstLayerMenu_GET', '011403_只能添加一層菜單_GET'),
562 ('crm_011404_only_add_FirstLayerMenu_POST', '011404_只能添加一層菜單_POST'),
563 ('crm_011405_only_change_FirstLayerMenu_GET', '011405_只能修改一層菜單_GET'),
564 ('crm_011406_only_change_FirstLayerMenu_POST', '011406_只能修改一層菜單_POST'),
565 ('crm_011407_only_delete_FirstLayerMenu_GET', '011407_只能刪除一層菜單_GET'),
566 ('crm_011408_only_delete_FirstLayerMenu_POST', '011408_只能刪除一層菜單_POST'),
567
568 ('crm_011501_only_view_SubMenu_GET', '011501_只能查看二層菜單_GET'),
569 ('crm_011502_only_view_SubMenu_POST', '011502_只能查看二層菜單_POST'),
570 ('crm_011503_only_add_SubMenu_GET', '011503_只能添加二層菜單_GET'),
571 ('crm_011504_only_add_SubMenu_POST', '011504_只能添加二層菜單_POST'),
572 ('crm_011505_only_change_SubMenu_GET', '011505_只能修改二層菜單_GET'),
573 ('crm_011506_only_change_SubMenu_POST', '011506_只能修改二層菜單_POST'),
574 ('crm_011507_only_delete_SubMenu_GET', '011507_只能刪除二層菜單_GET'),
575 ('crm_011508_only_delete_SubMenu_POST', '011508_只能刪除二層菜單_POST'),
576
577 ('crm_011601_only_view_Groups_GET', '011601_只能查看權限組_GET'),
578 ('crm_011602_only_view_Groups_POST', '011602_只能查看權限組_POST'),
579 ('crm_011603_only_add_Groups_GET', '011603_只能添加權限組_GET'),
580 ('crm_011604_only_add_Groups_POST', '011604_只能添加權限組_POST'),
581 ('crm_011605_only_change_Groups_GET', '011605_只能修改權限組_GET'),
582 ('crm_011606_only_change_Groups_POST', '011606_只能修改權限組_POST'),
583 ('crm_011607_only_delete_Groups_GET', '011607_只能刪除權限組_GET'),
584 ('crm_011608_only_delete_Groups_POST', '011608_只能刪除權限組_POST'),
585
586 ('crm_011701_own_password_reset_GET', '011701_自己密碼重置_GET'),
587 ('crm_011702_own_password_reset_POST', '011702_自己密碼重置_POST'),
588
589 ('crm_020101_all_not_audit_GET', '020101_銷售查看全部的客戶未審核_GET'),
590 ('crm_020103_all_enrollment_GET', '020103_銷售給全部的客戶報名課程_GET'),
591 ('crm_020104_all_enrollment_POST', '020104_銷售給全部的客戶報名課程_POST'),
592 ('crm_020105_all_contract_review_GET', '020105_銷售給全部的客戶審核合同_GET'),
593 ('crm_020116_all_contract_review_POST', '020116_銷售給全部的客戶審核合同_POST'),
594
595 ('crm_020201_own_enrollment_GET', '020201_銷售給自己的客戶報名課程_GET'),
596 ('crm_020202_own_enrollment_POST', '020202_銷售給自己的客戶報名課程_POST'),
597 ('crm_020203_own_contract_review_GET', '020203_銷售給自己的客戶審核合同_GET'),
598 ('crm_020204_own_contract_review_POST', '020204_銷售給自己的客戶審核合同_POST'),
599
600 ('crm_030101_all_not_payment_GET', '030101_財務查看全部的客戶未繳費_GET'),
601 ('crm_030102_all_not_payment_POST', '030102_財務查看全部的客戶未繳費_POST'),
602 ('crm_030103_all_already_payment_GET', '030103_財務查看全部的客戶已繳費_GET'),
603 ('crm_030104_all_already_payment_POST', '030104_財務查看全部的客戶已繳費_POST'),
604 ('crm_030105_all_payment_GET', '030105_財務進行全部的客戶繳費_GET'),
605 ('crm_030106_all_payment_POST', '030106_財務進行全部的客戶繳費_POST'),
606
607 ('crm_040101_own_student_course_GET', '040101_學生查看自己的課程_GET'),
608 ('crm_040102_own_student_course_POST', '040102_學生查看自己的課程_POST'),
609 ('crm_040103_own_studyrecords_GET', '040103_學生自己的上課記錄_GET'),
610 ('crm_040104_own_studyrecords_POST', '040104_學生自己的上課記錄_POST'),
611 ('crm_040105_own_homework_detail_GET', '040105_學生自己的作業詳情_GET'),
612 ('crm_040106_own_homework_detail_POST', '040106_學生自己的作業詳情_POST'),
613
614 ('crm_050101_own_teacher_class_GET', '050101_講師查看自己的班級_GET'),
615 ('crm_050102_own_teacher_class_POST', '050102_講師查看自己的班級_POST'),
616 ('crm_050103_own_teacher_class_detail_GET', '050103_講師查看自己的課節詳情_GET'),
617 ('crm_050104_own_teacher_class_detail_POST', '050104_講師查看自己的課節詳情_POST'),
618 ('crm_050105_own_teacher_lesson_detail_GET', '050105_講師查看自己的課節學員_GET'),
619 ('crm_050106_own_teacher_lesson_detail_POST', '050106_講師查看自己的課節學員_POST'),
620 ('crm_050107_own_howk_down_GET', '050107_講師自己的學員作業下載_GET'),
621 ('crm_050108_own_howk_down_POST', '050108_講師自己的學員作業下載_POST'),
622
623 ('crm_060101_own_coursetop_details_GET', '060101_講師查看自己的班級排名詳情_GET'),
624 ('crm_060102_own_coursetop_details_POST', '060102_講師查看自己的班級排名詳情_POST'),
625 ('crm_060103_own_coursetop_score_GET', '060103_講師查看自己的班級分數排行_GET'),
626 ('crm_060104_own_coursetop_score_POST', '060104_講師查看自己的班級排分數排行_POST'),
627 ('crm_060105_own_coursetop_homework_GET', '060105_講師查看自己的班級作業排行_GET'),
628 ('crm_060106_own_coursetop_homework_POST', '060106_講師查看自己的班級作業排行_POST'),
629 ('crm_060107_own_coursetop_attendance_GET', '060107_講師查看自己的班級出勤排行_GET'),
630 ('crm_060108_own_coursetop_attendance_POST', '060108_講師查看自己的班級出勤排行_POST'),
631
632 )
633 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
634 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
635 """15權限組"""
636 from django.contrib.auth.models import Group
637 class Groups(Group):
638 class Meta:
639 verbose_name_plural = '15權限組'
640 # ————————74PerfectCRM實現CRM權限和權限組限制URL————————
641 # ————————75PerfectCRM實現CRM擴展權限————————
642 from django.contrib.auth.models import Permission
643 class Permissions(Permission):
644 dic_name = models.CharField(_('dic_name'), max_length=255)
645 class Meta:
646 verbose_name_plural = "16擴展權限"
647 # ————————75PerfectCRM實現CRM擴展權限————————
648
649
650 """11角色表"""
651 class Role(models.Model):
652 name = models.CharField(unique=True,max_length=32)#角色名#CharField定長文本#角色名不可以重復#最長度=32字節
653
654 # ————————72PerfectCRM實現CRM動態菜單和角色————————
655 menus = models.ManyToManyField('FirstLayerMenu',verbose_name='一層菜單',blank=True)
656 # ————————72PerfectCRM實現CRM動態菜單和角色————————
657
658 def __str__(self):#__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
659 return self.name#返回 #角色名
660 class Meta: #通過一個內嵌類 "class Meta" 給你的 model 定義元數據
661 verbose_name_plural = "11角色表" #verbose_name_plural給你的模型類起一個更可讀的名字
662
663
664 """12標簽表"""
665 class Tag(models.Model):
666 name = models.CharField(max_length=64,unique=True) #標簽名#CharField定長文本#最長度=64字節#不可以重復
667 def __str__(self): #__str__()是Python的一個“魔幻”方法,這個方法定義了當object調用str()時應該返回的值。
668 return self.name #返回 #標簽名
669 class Meta:#通過一個內嵌類 "class Meta" 給你的 model 定義元數據
670 verbose_name_plural = "12標簽表" #verbose_name_plural給你的模型類起一個更可讀的名字
671
672 # ————————01PerfectCRM基本配置ADMIN————————
673
674
675 # ————————72PerfectCRM實現CRM動態菜單和角色————————
676 """13一層菜單名"""
677 class FirstLayerMenu(models.Model):
678 '''第一層側邊欄菜單'''
679 name = models.CharField('一層菜單名',max_length=64)
680 url_type_choices = ((0,'相關的名字'),(1,'固定的URL'))
681 url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
682 url_name = models.CharField(max_length=64,verbose_name='一層菜單路徑')
683 order = models.SmallIntegerField(default=0,verbose_name='菜單排序')
684 sub_menus = models.ManyToManyField('SubMenu',blank=True)
685
686 def __str__(self):
687 return self.name
688
689 class Meta:
690 verbose_name_plural = "13第一層菜單"
691
692 """14二層菜單名"""
693 class SubMenu(models.Model):
694 '''第二層側邊欄菜單'''
695 name = models.CharField('二層菜單名', max_length=64)
696 url_type_choices = ((0,'相關的名字'),(1,'固定的URL'))
697 url_type = models.SmallIntegerField(choices=url_type_choices,default=0)
698 url_name = models.CharField(max_length=64, verbose_name='二層菜單路徑')
699 order = models.SmallIntegerField(default=0, verbose_name='菜單排序')
700
701 def __str__(self):
702 return self.name
703
704 class Meta:
705 verbose_name_plural = "14第二層菜單"
706 # ————————72PerfectCRM實現CRM動態菜單和角色————————